From 7e57a6ec0a316e382d50918a48b9210f5f125955 Mon Sep 17 00:00:00 2001 From: Md Samsul Islam <56156956+mislam17@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:09:53 +0530 Subject: [PATCH 1/3] Histograms updated The variables in "hMuDeltaPtBeforeAccCuts" and hMuDeltaPtAfterAccCuts" are updated --- PWGHF/HFL/Tasks/taskSingleMuonMult.cxx | 28 ++++++++++++-------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx b/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx index f755dfac5e2..39f0d7a29dc 100644 --- a/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx +++ b/PWGHF/HFL/Tasks/taskSingleMuonMult.cxx @@ -71,6 +71,7 @@ struct HfTaskSingleMuonMult { Configurable rAbsorbMin{"rAbsorbMin", 17.6, "R at absorber end minimum value"}; Configurable rAbsorbMax{"rAbsorbMax", 89.5, "R at absorber end maximum value"}; Configurable rAbsorbMid{"rAbsorbMid", 26.5, "R at absorber end split point for different p*DCA selections"}; + Configurable chi2Max{"chi2Max", 1e6f, "MCH-MFT matching chi2 maximum value"}; Configurable reduceOrphMft{"reduceOrphMft", true, "reduce orphan MFT tracks"}; using MyCollisions = soa::Join; @@ -95,7 +96,7 @@ struct HfTaskSingleMuonMult { AxisSpec const axisNCh{500, 0.5, 500.5, "#it{N}_{ch}"}; AxisSpec const axisNMu{20, -0.5, 19.5, "#it{N}_{#mu}"}; AxisSpec const axisPt{1000, 0., 500., "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec const axisEta{250, -5., 5., "#it{#eta}"}; + AxisSpec const axisEta{1000, -5., 5., "#it{#eta}"}; AxisSpec const axisTheta{500, 170., 180., "#it{#theta}"}; AxisSpec const axisRAbsorb{1000, 0., 100., "#it{R}_{Absorb} (cm)"}; AxisSpec const axisDCA{500, 0., 5., "#it{DCA}_{xy} (cm)"}; @@ -118,13 +119,13 @@ struct HfTaskSingleMuonMult { registry.add("hMuBeforeMatchMFT", "Muon information before any Kinemeatic cuts applied", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("hMuBeforeAccCuts", "Muon information before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("h3DCABeforeAccCuts", "DCAx,DCAy,DCAz information before Acceptance cuts", {HistType::kTH3F, {axisDCAx, axisDCAx, axisTrackType}}); - registry.add("hMuDeltaPtBeforeAccCuts", "Muon information with DeltaPt before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisDeltaPt}, 10}); + registry.add("hMuDeltaPtBeforeAccCuts", "Muon information with DeltaPt before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDeltaPt, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("hMuAfterEtaCuts", "Muon information after applying Eta cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("hMuAfterRAbsorbCuts", "Muon information after applying RAbsorb cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("hMuAfterPdcaCuts", "Muon information after applying Pdca cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("hMuAfterAccCuts", "Muon information after applying all Kinematic cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("h3DCAAfterAccCuts", "DCAx,DCAy,DCAz information after Acceptance cuts", {HistType::kTH3F, {axisDCAx, axisDCAx, axisTrackType}}); - registry.add("hMuDeltaPtAfterAccCuts", "Muon information with DeltaPt after applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisDeltaPt}, 10}); + registry.add("hMuDeltaPtAfterAccCuts", "Muon information with DeltaPt after applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDeltaPt, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); registry.add("hTHnTrk", "Muon information with multiplicity", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisSign}, 5}); registry.add("h3MultNchNmu", "Number of muons and multiplicity", {HistType::kTH3F, {axisCent, axisNCh, axisNMu}}); @@ -192,6 +193,7 @@ struct HfTaskSingleMuonMult { const auto pt{muon.pt()}, eta{muon.eta()}, theta{90.0f - ((std::atan(muon.tgl())) * constants::math::Rad2Deg)}, pDca{muon.pDca()}, rAbsorb{muon.rAtAbsorberEnd()}, chi2{muon.chi2MatchMCHMFT()}; const auto dcaXY{RecoDecay::sqrtSumOfSquares(muon.fwdDcaX(), muon.fwdDcaY())}; const auto muTrackType{muon.trackType()}; + float dptBefore{0.}, dptAfter{0.}; registry.fill(HIST("hMuBeforeMatchMFT"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); @@ -202,11 +204,9 @@ struct HfTaskSingleMuonMult { if (muon.has_matchMCHTrack()) { auto muonType3 = muon.template matchMCHTrack_as(); - auto dpt = muonType3.pt() - pt; - if (muTrackType == ForwardTrackTypeEnum::GlobalMuonTrack) { - registry.fill(HIST("hMuDeltaPtBeforeAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, dpt); - } + dptBefore = muonType3.pt() - pt; } + registry.fill(HIST("hMuDeltaPtBeforeAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dptBefore, pDca, chi2, muTrackType); // Apply various standard muon acceptance cuts // eta cuts @@ -233,7 +233,7 @@ struct HfTaskSingleMuonMult { registry.fill(HIST("hMuAfterPdcaCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); // MCH-MFT matching chi2 - if (muon.chi2() >= 1e6) { + if (muon.chi2() >= chi2Max) { continue; } registry.fill(HIST("hMuonSel"), Chi2Cut); @@ -241,17 +241,15 @@ struct HfTaskSingleMuonMult { // histograms after acceptance cuts registry.fill(HIST("hMuAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); registry.fill(HIST("h3DCAAfterAccCuts"), muon.fwdDcaX(), muon.fwdDcaY(), muTrackType); - nMu++; - nMuType[muTrackType]++; if (muon.has_matchMCHTrack()) { auto muonType3 = muon.template matchMCHTrack_as(); - auto dpt = muonType3.pt() - pt; - - if (muTrackType == ForwardTrackTypeEnum::GlobalMuonTrack) { - registry.fill(HIST("hMuDeltaPtAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, dpt); - } + dptAfter = muonType3.pt() - pt; } + registry.fill(HIST("hMuDeltaPtAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dptAfter, pDca, chi2, muTrackType); + + nMu++; + nMuType[muTrackType]++; } registry.fill(HIST("h3MultNchNmu"), cent, nCh, nMu); From 5afacdfd065e7d755d1470aaac32cc728660a076 Mon Sep 17 00:00:00 2001 From: Md Samsul Islam <56156956+mislam17@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:14:02 +0530 Subject: [PATCH 2/3] task for single muon identification in MC simulation and Axe calculation This file implements a task for identifying various sources of single muons and Axe calculation in Monte Carlo simulations. --- PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx | 535 +++++++++++++++++++++++ 1 file changed, 535 insertions(+) create mode 100644 PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx diff --git a/PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx b/PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx new file mode 100644 index 00000000000..1f67d77b14d --- /dev/null +++ b/PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx @@ -0,0 +1,535 @@ +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. +// All rights not expressly granted are reserved. +// +// This software is distributed under the terms of the GNU General Public +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. +// +/// \file taskSingleMuonMultMc.cxx +/// \brief Task used to identify various sources of single muons and to calculated Axe in Monte Carlo simulation. +/// \author Md Samsul Islam , IITB + +#include "Common/Core/RecoDecay.h" +#include "Common/DataModel/EventSelection.h" +#include "Common/DataModel/TrackSelectionTables.h" + +#include "CommonConstants/PhysicsConstants.h" +#include "Framework/ASoAHelpers.h" +#include "Framework/AnalysisDataModel.h" +#include "Framework/AnalysisTask.h" +#include "Framework/HistogramRegistry.h" +#include "Framework/O2DatabasePDGPlugin.h" +#include "Framework/runDataProcessing.h" +#include "ReconstructionDataFormats/TrackFwd.h" +#include + +#include + +using namespace o2; +using namespace o2::aod; +using namespace o2::framework; +using namespace o2::framework::expressions; +using namespace o2::aod::fwdtrack; + +auto static constexpr MinCharge = 3.f; + +namespace +{ +enum ParticleType { + IsIdentified = 0, // this particle is identified + IsMuon, // this is a muon + IsSecondary, // this is a secondary particle + HasTauParent, // this particle has a tau parent + HasWParent, // this particle has a W parent + HasZParent, // this particle has a Z parent + HasLightParent, // this particle has a light flavor parent + HasQuarkoniumParent, // this particle has a quarkonium parent + HasCharmParent, // this particle has a charm parent + HasBeautyParent // this particle has a beauty parent +}; +} // namespace + +struct HfTaskSingleMuonMultMc { + SliceCache cache; + Preslice perCol = aod::track::collisionId; + Preslice perMcCol = aod::mcparticle::mcCollisionId; + o2::framework::Service pdg; + + Configurable mcMaskSelection{"mcMaskSelection", 0, "McMask for correct match, valid values are 0 and 128"}; + Configurable pdgQuark{"pdgQuark", 10, "pdg Max for Quarks"}; + Configurable pdgRemMin{"pdgRemMin", 100, " Min. pdg Remnant for calculating Hadron pdg"}; + Configurable pdgRemMax{"pdgRemMax", 10000, "Max. pdg Remnant for calculating Hadron pdg"}; + Configurable flvMin{"flvMin", 4, "Min flavor of constituent quark"}; + Configurable flvMax{"flvMax", 6, "Max flavor of constituent quark"}; + Configurable flvLeading{"flvLeading", 10, "Base to extract leading flavor of constituent quark"}; + + Configurable charge{"charge", -1, "Muon track charge, validated values are 0, 1 and -1, 0 represents both 1 and -1"}; + Configurable zVtxMax{"zVtxMax", 10., "maxium z of primary vertex [cm]"}; + Configurable ptTrackMin{"ptTrackMin", 0.15, "minimum pt of tracks"}; + Configurable etaTrackMax{"etaTrackMax", 0.8, "maximum pseudorapidity of tracks"}; + Configurable etaMin{"etaMin", -3.6, "minimum pseudorapidity"}; + Configurable etaMax{"etaMax", -2.5, "maximum pseudorapidity"}; + Configurable pDcaMin{"pDcaMin", 324., "p*DCA value for small RAbsorb"}; + Configurable pDcaMax{"pDcaMax", 594., "p*DCA value for large RAbsorb"}; + Configurable rAbsorbMin{"rAbsorbMin", 17.6, "R at absorber end minimum value"}; + Configurable rAbsorbMax{"rAbsorbMax", 89.5, "R at absorber end maximum value"}; + Configurable rAbsorbMid{"rAbsorbMid", 26.5, "R at absorber end split point for different p*DCA selections"}; + + using MyCollisions = soa::Join; + using McMuons = soa::Join; + using MyTracks = soa::Filtered>; + using McGenCollisions = soa::Join; + using McRecCollisions = soa::SmallGroups>; + + // Filter Global Track for Multiplicty + Filter trackFilter = ((nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin)); + + HistogramRegistry registry{ + "registry", + {}, + OutputObjHandlingPolicy::AnalysisObject, + true, + true}; + + void init(InitContext&) + { + const TString muonSources[]{ + "Identified", + "Muon", + "SecondaryMu", + "LightDecayMu", + "TauDecayMu", + "WBosonDecayMu", + "ZBosonDecayMu", + "QuarkoniumDecayMu", + "BeautyMu", + "BeautyDecayMu", + "NonpromptCharmMu", + "PromptCharmMu", + "OtherMu", + "Hadron", + "Unidentified"}; + + AxisSpec axisColNumber{1, 0.5, 1.5, "Selected collisions"}; + AxisSpec axisMcMask{1001, -500.5, 500.5, "Mc Mask Selection"}; + AxisSpec axisMcLabel{1001, -500.5, 500.5, "McLabel"}; + AxisSpec axisNCh{500, 0.5, 500.5, "#it{N}_{ch}"}; + AxisSpec axisNtrk{500, 0.5, 500.5, "#it{N}_{trk}"}; + AxisSpec axisPt{5000, 0., 500., "#it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisEta{1000, -5., 5., "#it{#eta}"}; + AxisSpec axisRAbsorb{1000, 0., 100., "#it{R}_{Absorb} (cm)"}; + AxisSpec axisDCA{500, 0., 5., "#it{DCA}_{xy} (cm)"}; + AxisSpec axisChi2{1000, 0., 1000., "MCH-MFT matching #chi^{2}"}; + AxisSpec axisPDca{100000, 0, 100000, "#it{p} #times DCA (GeV/#it{c} * cm)"}; + AxisSpec axisDeltaPt{10000, -50, 50, "#Delta #it{p}_{T} (GeV/#it{c})"}; + AxisSpec axisTrackType{8, -1.5, 6.5, "TrackType"}; + AxisSpec axisZ{1000, -50, 50, "V_{z} axis"}; + AxisSpec axisCharge{21, -10.5, 10.5, "charge"}; + AxisSpec axisPDG{201, -100.5, 100.5, "PDG"}; + AxisSpec axisMuonMask{15, -0.5, 14.5, "MuonMask"}; + + HistogramConfigSpec hNEventGen{HistType::kTH1F, {axisColNumber}}; + HistogramConfigSpec hNEventRec{HistType::kTH1F, {axisColNumber}}; + HistogramConfigSpec hParticleGen{HistType::kTHnSparseF, {axisPt, axisEta}}; + HistogramConfigSpec hParticleRec{HistType::kTHnSparseF, {axisPt, axisEta}}; + HistogramConfigSpec hTrackResponse{HistType::kTH2F, {axisNCh, axisNtrk}}; + + HistogramConfigSpec hMcMask{HistType::kTH1F, {axisMcMask}}; + HistogramConfigSpec hMuMcLabel{HistType::kTH1F, {axisMcLabel}}; + HistogramConfigSpec hMuTrackType{HistType::kTH1F, {axisTrackType}}; + HistogramConfigSpec hNEventGenMu{HistType::kTH1F, {axisColNumber}}; + HistogramConfigSpec hNEventRecMu{HistType::kTH1F, {axisColNumber}}; + HistogramConfigSpec hGenMuVar{HistType::kTHnSparseF, {axisPDG, axisPt, axisEta}}; + HistogramConfigSpec hRecMuVar{HistType::kTHnSparseF, {axisPDG, axisPt, axisEta}}; + HistogramConfigSpec hMuAfterAccCuts{HistType::kTHnSparseF, {axisPDG, axisPt, axisEta, axisRAbsorb, axisDCA, axisPDca, axisChi2, axisTrackType}}; + + registry.add("hNEventRec", "", hNEventRec); + registry.add("hNEventGen", "", hNEventGen); + registry.add("hParticleGen", "Generated particles ", hParticleGen); + registry.add("hParticleRec", "Reconstructed particles", hParticleRec); + registry.add("hTrackResponse", "Generation-Recontsruction Response", hTrackResponse); + + registry.add("hMcMask", "Muon mcMask", hMcMask); + registry.add("hMuMcLabel", "Muon mcLabel", hMuMcLabel); + registry.add("hMuTrackType", "PDG code", hMuTrackType); + registry.add("hNEventGenMu", "Muon Generated", hNEventGenMu); + registry.add("hNEventRecMu", "Muon Reconstruced", hNEventRecMu); + registry.add("hGenMuVar", "Muon Generated Variables", hGenMuVar); + registry.add("hRecMuVar", "Muon Reconstructed Variables", hRecMuVar); + registry.add("hMuAfterAccCuts", "Muon Reconstructed Variables", hMuAfterAccCuts); + + for (const auto& src : muonSources) { + registry.add(Form("h2%s", src.Data()), "", {HistType::kTH2F, {axisPt, axisEta}}); + } + } + + // get the bitmask for muon sources identification + uint16_t getMask(const McMuons::iterator& muon) + { + uint16_t mask(0); + if (!muon.has_mcParticle()) { + return mask; + } + SETBIT(mask, IsIdentified); + + auto mcPart(muon.mcParticle()); + if (std::abs(mcPart.pdgCode()) != kMuonMinus) { + return mask; + } + SETBIT(mask, IsMuon); + + while (mcPart.has_mothers()) { + mcPart = *(mcPart.mothers_first_as()); + const int pdgAbs = std::abs(mcPart.pdgCode()); + + // Stop at quark + if (pdgAbs < pdgQuark) { + break; + } + + // Produced in transport code + if (!mcPart.producedByGenerator()) { + SETBIT(mask, IsSecondary); + continue; + } + + // Tau parent + if (pdgAbs == kTauMinus) { + SETBIT(mask, HasTauParent); + continue; + } + + // W boson + if (pdgAbs == kWPlus) { + SETBIT(mask, HasWParent); + continue; + } + + // Z boson + if (pdgAbs == kZ0) { + SETBIT(mask, HasZParent); + continue; + } + + const int pdgRem(pdgAbs % 100000); + + if (pdgRem == kProton) { + continue; + } // Beam particle + + if ((pdgRem < pdgRemMin) || (pdgRem >= pdgRemMax)) { + continue; + } + // compute the leding flavor of constituent quark + int flv(pdgRem); + while (flv >= flvLeading) { + flv /= flvLeading; + } + + if (flv > flvMax) { + // no more than 6 flavors + continue; + } + if (flv < flvMin) { + // light flavor + SETBIT(mask, HasLightParent); + continue; + } + + auto pdgData(pdg->GetParticle(mcPart.pdgCode())); + if (pdgData && (pdgData->AntiParticle() == nullptr)) { + SETBIT(mask, HasQuarkoniumParent); + continue; + } else if (flv == flvMin) { + SETBIT(mask, HasCharmParent); + continue; + } else { + SETBIT(mask, HasBeautyParent); + continue; + } + } + + return mask; + } + + // particle has an associated MC particle + bool isIdentified(const uint16_t& mask) + { + return (TESTBIT(mask, IsIdentified)); + } + // this particle is muon + bool isMuon(const uint16_t& mask) + { + return (TESTBIT(mask, IsIdentified) && TESTBIT(mask, IsMuon)); + } + + // this muon comes from transport + bool isSecondaryMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, IsSecondary)); + } + + // this muon comes from light flavor quark decay + bool isLightDecayMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasLightParent) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes from tau decays + bool isTauDecayMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasTauParent) && (!TESTBIT(mask, HasWParent)) && (!TESTBIT(mask, HasZParent)) && (!TESTBIT(mask, HasBeautyParent)) && (!TESTBIT(mask, HasCharmParent))); + } + + // this muon comes from W+- decay + bool isWBosonDecayMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasWParent) && (!TESTBIT(mask, HasZParent)) && (!TESTBIT(mask, HasTauParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes from Z decay + bool isZBosonDecayMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasZParent) && (!TESTBIT(mask, HasWParent)) && (!TESTBIT(mask, HasTauParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes from quarkonium decay + bool isQuarkoniumDecayMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasQuarkoniumParent) && (!TESTBIT(mask, HasBeautyParent)) && (!TESTBIT(mask, HasCharmParent)) && (!TESTBIT(mask, HasLightParent))); + } + + // this muon comes from beauty decay and does not have light flavor parent + bool isBeautyMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasBeautyParent) && (!TESTBIT(mask, HasQuarkoniumParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes directly from beauty decay + bool isBeautyDecayMu(const uint16_t& mask) + { + return (isBeautyMu(mask) && (!TESTBIT(mask, HasCharmParent) && (!TESTBIT(mask, HasQuarkoniumParent))) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes from non-prompt charm decay and does not have light flavor parent + bool isNonpromptCharmMu(const uint16_t& mask) + { + return (isBeautyMu(mask) && TESTBIT(mask, HasCharmParent) && (!TESTBIT(mask, HasQuarkoniumParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes from prompt charm decay and does not have light flavor parent + bool isPromptCharmMu(const uint16_t& mask) + { + return (isMuon(mask) && TESTBIT(mask, HasCharmParent) && (!TESTBIT(mask, HasBeautyParent)) && (!TESTBIT(mask, HasQuarkoniumParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); + } + + // this muon comes from other sources which have not classified above. + bool isOtherMu(const uint16_t& mask) + { + return (isMuon(mask) && (!isSecondaryMu(mask)) && (!isLightDecayMu(mask)) && (!isTauDecayMu(mask)) && (!isWBosonDecayMu(mask)) && (!isZBosonDecayMu(mask)) && (!isQuarkoniumDecayMu(mask)) && (!isBeautyMu(mask)) && (!isPromptCharmMu(mask))); + } + + // this is a hadron + bool isHadron(const uint16_t& mask) + { + return (TESTBIT(mask, IsIdentified) && (!TESTBIT(mask, IsMuon))); + } + + // this particle is unidentified + bool isUnidentified(const uint16_t& mask) + { + return ((!TESTBIT(mask, IsIdentified))); + } + + // fill the histograms of each particle types + void fillHistograms(const McMuons::iterator& muon) + { + const auto mask(getMask(muon)); + const auto pt(muon.pt()), eta(muon.eta()); + + if (isIdentified(mask)) { + registry.fill(HIST("h2Identified"), pt, eta); + } + if (isMuon(mask)) { + registry.fill(HIST("h2Muon"), pt, eta); + } + if (isSecondaryMu(mask)) { + registry.fill(HIST("h2SecondaryMu"), pt, eta); + } + if (isLightDecayMu(mask)) { + registry.fill(HIST("h2LightDecayMu"), pt, eta); + } + if (isTauDecayMu(mask)) { + registry.fill(HIST("h2TauDecayMu"), pt, eta); + } + if (isWBosonDecayMu(mask)) { + registry.fill(HIST("h2WBosonDecayMu"), pt, eta); + } + if (isZBosonDecayMu(mask)) { + registry.fill(HIST("h2ZBosonDecayMu"), pt, eta); + } + if (isQuarkoniumDecayMu(mask)) { + registry.fill(HIST("h2QuarkoniumDecayMu"), pt, eta); + } + if (isBeautyMu(mask)) { + registry.fill(HIST("h2BeautyMu"), pt, eta); + } + if (isBeautyDecayMu(mask)) { + registry.fill(HIST("h2BeautyDecayMu"), pt, eta); + } + if (isNonpromptCharmMu(mask)) { + registry.fill(HIST("h2NonpromptCharmMu"), pt, eta); + } + if (isPromptCharmMu(mask)) { + registry.fill(HIST("h2PromptCharmMu"), pt, eta); + } + if (isOtherMu(mask)) { + registry.fill(HIST("h2OtherMu"), pt, eta); + } + if (isHadron(mask)) { + registry.fill(HIST("h2Hadron"), pt, eta); + } + if (isUnidentified(mask)) { + registry.fill(HIST("h2Unidentified"), pt, eta); + } + } + + void process(McGenCollisions::iterator const& mccollision, McMuons const& muons, aod::McParticles const&, McRecCollisions const& collisions) + { + + // event selections + if (std::abs(mccollision.posZ()) > zVtxMax) { + return; + } + + registry.fill(HIST("hNEventGenMu"), 1); + + for (const auto& muon : muons) { + if (!(muon.has_mcParticle())) { + continue; + } + auto mcPart(muon.mcParticle()); + auto pdgGen(mcPart.pdgCode()); + auto etaGen(mcPart.eta()); + + if (!(std::abs(pdgGen) == kMuonMinus)) { + continue; + } + if ((etaGen >= etaMax) || (etaGen < etaMin)) { + continue; + } + registry.fill(HIST("hGenMuVar"), pdgGen, mcPart.pt(), etaGen); + } + + for (const auto& collision : collisions) { + if (std::abs(collision.posZ()) > zVtxMax) { + continue; + } + registry.fill(HIST("hNEventRecMu"), 1); + + for (const auto& muon : muons) { + // muon selections + registry.fill(HIST("hMcMask"), muon.mcMask()); + + if (muon.mcMask() != mcMaskSelection) { + continue; + } + + if (!(muon.has_mcParticle())) { + continue; + } + const auto pt(muon.pt()), eta(muon.eta()), rAbsorb(muon.rAtAbsorberEnd()), pDca(muon.pDca()), chi2(muon.chi2MatchMCHMFT()); + const auto dcaXY{RecoDecay::sqrtSumOfSquares(muon.fwdDcaX(), muon.fwdDcaY())}; + const auto muTrackType{muon.trackType()}; + const auto mcLabel(muon.mcParticleId()); + + if (mcLabel < 0) { + continue; + } + + registry.fill(HIST("hMuMcLabel"), mcLabel); + registry.fill(HIST("hMuTrackType"), muTrackType); + + auto mcparticle(muon.mcParticle()); + const auto pdg(mcparticle.pdgCode()); + + if ((eta >= etaMax) || (eta < etaMin)) { + continue; + } + if ((rAbsorb >= rAbsorbMax) || (rAbsorb < rAbsorbMin)) { + continue; + } + if (pDca >= pDcaMax) { + continue; + } + registry.fill(HIST("hRecMuVar"), pdg, pt, eta); + registry.fill(HIST("hMuAfterAccCuts"), pdg, pt, eta, rAbsorb, dcaXY, pDca, chi2, muTrackType); + + fillHistograms(muon); + } + } + } + + void processResTrack(McGenCollisions::iterator const& mccollision, McRecCollisions const& collisions, aod::McParticles const& particles, MyTracks const& tracks) + { + // event selections + if (std::abs(mccollision.posZ()) > zVtxMax) { + return; + } + registry.fill(HIST("hNEventGen"), 1.); + auto nP = 0; + for (const auto& particle : particles) { + if (!particle.isPhysicalPrimary()) { + continue; + } + if (!particle.producedByGenerator()) { + continue; + } + + auto charge = 0.; + auto* p = pdg->GetParticle(particle.pdgCode()); + if (p != nullptr) { + charge = p->Charge(); + } + + if (std::abs(charge) < MinCharge) { + continue; + } + if (particle.pt() < ptTrackMin || std::abs(particle.eta()) >= etaTrackMax) { + continue; + } + + registry.fill(HIST("hParticleGen"), particle.pt(), particle.eta()); + nP++; + } + for (const auto& collision : collisions) { + if (std::abs(collision.posZ()) > zVtxMax) { + continue; + } + registry.fill(HIST("hNEventRec"), 1.); + auto nTrk = 0; + auto tracksample = tracks.sliceBy(perCol, collision.globalIndex()); + for (const auto& track : tracksample) { + if (!track.isGlobalTrack()) + continue; + registry.fill(HIST("hParticleRec"), track.pt(), track.eta()); + ++nTrk; + } + if (nTrk < 1) + continue; + registry.fill(HIST("hTrackResponse"), nP, nTrk); + } + } + PROCESS_SWITCH(HfTaskSingleMuonMultMc, processResTrack, "Process Track Reconstruction/Generation", true); +}; + +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) +{ + return WorkflowSpec{ + adaptAnalysisTask(cfgc), + }; +} From c9ebb4ab369b09fbd0755a9172270ccf61b83285 Mon Sep 17 00:00:00 2001 From: Md Samsul Islam <56156956+mislam17@users.noreply.github.com> Date: Tue, 10 Feb 2026 13:58:58 +0530 Subject: [PATCH 3/3] Delete PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx --- PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx | 535 ----------------------- 1 file changed, 535 deletions(-) delete mode 100644 PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx diff --git a/PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx b/PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx deleted file mode 100644 index 1f67d77b14d..00000000000 --- a/PWGHF/HFL/Tasks/taskSingleMuonMultMc.cxx +++ /dev/null @@ -1,535 +0,0 @@ -// Copyright 2019-2020 CERN and copyright holders of ALICE O2. -// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. -// All rights not expressly granted are reserved. -// -// This software is distributed under the terms of the GNU General Public -// License v3 (GPL Version 3), copied verbatim in the file "COPYING". -// -// In applying this license CERN does not waive the privileges and immunities -// granted to it by virtue of its status as an Intergovernmental Organization -// or submit itself to any jurisdiction. -// -/// \file taskSingleMuonMultMc.cxx -/// \brief Task used to identify various sources of single muons and to calculated Axe in Monte Carlo simulation. -/// \author Md Samsul Islam , IITB - -#include "Common/Core/RecoDecay.h" -#include "Common/DataModel/EventSelection.h" -#include "Common/DataModel/TrackSelectionTables.h" - -#include "CommonConstants/PhysicsConstants.h" -#include "Framework/ASoAHelpers.h" -#include "Framework/AnalysisDataModel.h" -#include "Framework/AnalysisTask.h" -#include "Framework/HistogramRegistry.h" -#include "Framework/O2DatabasePDGPlugin.h" -#include "Framework/runDataProcessing.h" -#include "ReconstructionDataFormats/TrackFwd.h" -#include - -#include - -using namespace o2; -using namespace o2::aod; -using namespace o2::framework; -using namespace o2::framework::expressions; -using namespace o2::aod::fwdtrack; - -auto static constexpr MinCharge = 3.f; - -namespace -{ -enum ParticleType { - IsIdentified = 0, // this particle is identified - IsMuon, // this is a muon - IsSecondary, // this is a secondary particle - HasTauParent, // this particle has a tau parent - HasWParent, // this particle has a W parent - HasZParent, // this particle has a Z parent - HasLightParent, // this particle has a light flavor parent - HasQuarkoniumParent, // this particle has a quarkonium parent - HasCharmParent, // this particle has a charm parent - HasBeautyParent // this particle has a beauty parent -}; -} // namespace - -struct HfTaskSingleMuonMultMc { - SliceCache cache; - Preslice perCol = aod::track::collisionId; - Preslice perMcCol = aod::mcparticle::mcCollisionId; - o2::framework::Service pdg; - - Configurable mcMaskSelection{"mcMaskSelection", 0, "McMask for correct match, valid values are 0 and 128"}; - Configurable pdgQuark{"pdgQuark", 10, "pdg Max for Quarks"}; - Configurable pdgRemMin{"pdgRemMin", 100, " Min. pdg Remnant for calculating Hadron pdg"}; - Configurable pdgRemMax{"pdgRemMax", 10000, "Max. pdg Remnant for calculating Hadron pdg"}; - Configurable flvMin{"flvMin", 4, "Min flavor of constituent quark"}; - Configurable flvMax{"flvMax", 6, "Max flavor of constituent quark"}; - Configurable flvLeading{"flvLeading", 10, "Base to extract leading flavor of constituent quark"}; - - Configurable charge{"charge", -1, "Muon track charge, validated values are 0, 1 and -1, 0 represents both 1 and -1"}; - Configurable zVtxMax{"zVtxMax", 10., "maxium z of primary vertex [cm]"}; - Configurable ptTrackMin{"ptTrackMin", 0.15, "minimum pt of tracks"}; - Configurable etaTrackMax{"etaTrackMax", 0.8, "maximum pseudorapidity of tracks"}; - Configurable etaMin{"etaMin", -3.6, "minimum pseudorapidity"}; - Configurable etaMax{"etaMax", -2.5, "maximum pseudorapidity"}; - Configurable pDcaMin{"pDcaMin", 324., "p*DCA value for small RAbsorb"}; - Configurable pDcaMax{"pDcaMax", 594., "p*DCA value for large RAbsorb"}; - Configurable rAbsorbMin{"rAbsorbMin", 17.6, "R at absorber end minimum value"}; - Configurable rAbsorbMax{"rAbsorbMax", 89.5, "R at absorber end maximum value"}; - Configurable rAbsorbMid{"rAbsorbMid", 26.5, "R at absorber end split point for different p*DCA selections"}; - - using MyCollisions = soa::Join; - using McMuons = soa::Join; - using MyTracks = soa::Filtered>; - using McGenCollisions = soa::Join; - using McRecCollisions = soa::SmallGroups>; - - // Filter Global Track for Multiplicty - Filter trackFilter = ((nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin)); - - HistogramRegistry registry{ - "registry", - {}, - OutputObjHandlingPolicy::AnalysisObject, - true, - true}; - - void init(InitContext&) - { - const TString muonSources[]{ - "Identified", - "Muon", - "SecondaryMu", - "LightDecayMu", - "TauDecayMu", - "WBosonDecayMu", - "ZBosonDecayMu", - "QuarkoniumDecayMu", - "BeautyMu", - "BeautyDecayMu", - "NonpromptCharmMu", - "PromptCharmMu", - "OtherMu", - "Hadron", - "Unidentified"}; - - AxisSpec axisColNumber{1, 0.5, 1.5, "Selected collisions"}; - AxisSpec axisMcMask{1001, -500.5, 500.5, "Mc Mask Selection"}; - AxisSpec axisMcLabel{1001, -500.5, 500.5, "McLabel"}; - AxisSpec axisNCh{500, 0.5, 500.5, "#it{N}_{ch}"}; - AxisSpec axisNtrk{500, 0.5, 500.5, "#it{N}_{trk}"}; - AxisSpec axisPt{5000, 0., 500., "#it{p}_{T} (GeV/#it{c})"}; - AxisSpec axisEta{1000, -5., 5., "#it{#eta}"}; - AxisSpec axisRAbsorb{1000, 0., 100., "#it{R}_{Absorb} (cm)"}; - AxisSpec axisDCA{500, 0., 5., "#it{DCA}_{xy} (cm)"}; - AxisSpec axisChi2{1000, 0., 1000., "MCH-MFT matching #chi^{2}"}; - AxisSpec axisPDca{100000, 0, 100000, "#it{p} #times DCA (GeV/#it{c} * cm)"}; - AxisSpec axisDeltaPt{10000, -50, 50, "#Delta #it{p}_{T} (GeV/#it{c})"}; - AxisSpec axisTrackType{8, -1.5, 6.5, "TrackType"}; - AxisSpec axisZ{1000, -50, 50, "V_{z} axis"}; - AxisSpec axisCharge{21, -10.5, 10.5, "charge"}; - AxisSpec axisPDG{201, -100.5, 100.5, "PDG"}; - AxisSpec axisMuonMask{15, -0.5, 14.5, "MuonMask"}; - - HistogramConfigSpec hNEventGen{HistType::kTH1F, {axisColNumber}}; - HistogramConfigSpec hNEventRec{HistType::kTH1F, {axisColNumber}}; - HistogramConfigSpec hParticleGen{HistType::kTHnSparseF, {axisPt, axisEta}}; - HistogramConfigSpec hParticleRec{HistType::kTHnSparseF, {axisPt, axisEta}}; - HistogramConfigSpec hTrackResponse{HistType::kTH2F, {axisNCh, axisNtrk}}; - - HistogramConfigSpec hMcMask{HistType::kTH1F, {axisMcMask}}; - HistogramConfigSpec hMuMcLabel{HistType::kTH1F, {axisMcLabel}}; - HistogramConfigSpec hMuTrackType{HistType::kTH1F, {axisTrackType}}; - HistogramConfigSpec hNEventGenMu{HistType::kTH1F, {axisColNumber}}; - HistogramConfigSpec hNEventRecMu{HistType::kTH1F, {axisColNumber}}; - HistogramConfigSpec hGenMuVar{HistType::kTHnSparseF, {axisPDG, axisPt, axisEta}}; - HistogramConfigSpec hRecMuVar{HistType::kTHnSparseF, {axisPDG, axisPt, axisEta}}; - HistogramConfigSpec hMuAfterAccCuts{HistType::kTHnSparseF, {axisPDG, axisPt, axisEta, axisRAbsorb, axisDCA, axisPDca, axisChi2, axisTrackType}}; - - registry.add("hNEventRec", "", hNEventRec); - registry.add("hNEventGen", "", hNEventGen); - registry.add("hParticleGen", "Generated particles ", hParticleGen); - registry.add("hParticleRec", "Reconstructed particles", hParticleRec); - registry.add("hTrackResponse", "Generation-Recontsruction Response", hTrackResponse); - - registry.add("hMcMask", "Muon mcMask", hMcMask); - registry.add("hMuMcLabel", "Muon mcLabel", hMuMcLabel); - registry.add("hMuTrackType", "PDG code", hMuTrackType); - registry.add("hNEventGenMu", "Muon Generated", hNEventGenMu); - registry.add("hNEventRecMu", "Muon Reconstruced", hNEventRecMu); - registry.add("hGenMuVar", "Muon Generated Variables", hGenMuVar); - registry.add("hRecMuVar", "Muon Reconstructed Variables", hRecMuVar); - registry.add("hMuAfterAccCuts", "Muon Reconstructed Variables", hMuAfterAccCuts); - - for (const auto& src : muonSources) { - registry.add(Form("h2%s", src.Data()), "", {HistType::kTH2F, {axisPt, axisEta}}); - } - } - - // get the bitmask for muon sources identification - uint16_t getMask(const McMuons::iterator& muon) - { - uint16_t mask(0); - if (!muon.has_mcParticle()) { - return mask; - } - SETBIT(mask, IsIdentified); - - auto mcPart(muon.mcParticle()); - if (std::abs(mcPart.pdgCode()) != kMuonMinus) { - return mask; - } - SETBIT(mask, IsMuon); - - while (mcPart.has_mothers()) { - mcPart = *(mcPart.mothers_first_as()); - const int pdgAbs = std::abs(mcPart.pdgCode()); - - // Stop at quark - if (pdgAbs < pdgQuark) { - break; - } - - // Produced in transport code - if (!mcPart.producedByGenerator()) { - SETBIT(mask, IsSecondary); - continue; - } - - // Tau parent - if (pdgAbs == kTauMinus) { - SETBIT(mask, HasTauParent); - continue; - } - - // W boson - if (pdgAbs == kWPlus) { - SETBIT(mask, HasWParent); - continue; - } - - // Z boson - if (pdgAbs == kZ0) { - SETBIT(mask, HasZParent); - continue; - } - - const int pdgRem(pdgAbs % 100000); - - if (pdgRem == kProton) { - continue; - } // Beam particle - - if ((pdgRem < pdgRemMin) || (pdgRem >= pdgRemMax)) { - continue; - } - // compute the leding flavor of constituent quark - int flv(pdgRem); - while (flv >= flvLeading) { - flv /= flvLeading; - } - - if (flv > flvMax) { - // no more than 6 flavors - continue; - } - if (flv < flvMin) { - // light flavor - SETBIT(mask, HasLightParent); - continue; - } - - auto pdgData(pdg->GetParticle(mcPart.pdgCode())); - if (pdgData && (pdgData->AntiParticle() == nullptr)) { - SETBIT(mask, HasQuarkoniumParent); - continue; - } else if (flv == flvMin) { - SETBIT(mask, HasCharmParent); - continue; - } else { - SETBIT(mask, HasBeautyParent); - continue; - } - } - - return mask; - } - - // particle has an associated MC particle - bool isIdentified(const uint16_t& mask) - { - return (TESTBIT(mask, IsIdentified)); - } - // this particle is muon - bool isMuon(const uint16_t& mask) - { - return (TESTBIT(mask, IsIdentified) && TESTBIT(mask, IsMuon)); - } - - // this muon comes from transport - bool isSecondaryMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, IsSecondary)); - } - - // this muon comes from light flavor quark decay - bool isLightDecayMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasLightParent) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes from tau decays - bool isTauDecayMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasTauParent) && (!TESTBIT(mask, HasWParent)) && (!TESTBIT(mask, HasZParent)) && (!TESTBIT(mask, HasBeautyParent)) && (!TESTBIT(mask, HasCharmParent))); - } - - // this muon comes from W+- decay - bool isWBosonDecayMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasWParent) && (!TESTBIT(mask, HasZParent)) && (!TESTBIT(mask, HasTauParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes from Z decay - bool isZBosonDecayMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasZParent) && (!TESTBIT(mask, HasWParent)) && (!TESTBIT(mask, HasTauParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes from quarkonium decay - bool isQuarkoniumDecayMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasQuarkoniumParent) && (!TESTBIT(mask, HasBeautyParent)) && (!TESTBIT(mask, HasCharmParent)) && (!TESTBIT(mask, HasLightParent))); - } - - // this muon comes from beauty decay and does not have light flavor parent - bool isBeautyMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasBeautyParent) && (!TESTBIT(mask, HasQuarkoniumParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes directly from beauty decay - bool isBeautyDecayMu(const uint16_t& mask) - { - return (isBeautyMu(mask) && (!TESTBIT(mask, HasCharmParent) && (!TESTBIT(mask, HasQuarkoniumParent))) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes from non-prompt charm decay and does not have light flavor parent - bool isNonpromptCharmMu(const uint16_t& mask) - { - return (isBeautyMu(mask) && TESTBIT(mask, HasCharmParent) && (!TESTBIT(mask, HasQuarkoniumParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes from prompt charm decay and does not have light flavor parent - bool isPromptCharmMu(const uint16_t& mask) - { - return (isMuon(mask) && TESTBIT(mask, HasCharmParent) && (!TESTBIT(mask, HasBeautyParent)) && (!TESTBIT(mask, HasQuarkoniumParent)) && (!TESTBIT(mask, HasLightParent)) && (!TESTBIT(mask, IsSecondary))); - } - - // this muon comes from other sources which have not classified above. - bool isOtherMu(const uint16_t& mask) - { - return (isMuon(mask) && (!isSecondaryMu(mask)) && (!isLightDecayMu(mask)) && (!isTauDecayMu(mask)) && (!isWBosonDecayMu(mask)) && (!isZBosonDecayMu(mask)) && (!isQuarkoniumDecayMu(mask)) && (!isBeautyMu(mask)) && (!isPromptCharmMu(mask))); - } - - // this is a hadron - bool isHadron(const uint16_t& mask) - { - return (TESTBIT(mask, IsIdentified) && (!TESTBIT(mask, IsMuon))); - } - - // this particle is unidentified - bool isUnidentified(const uint16_t& mask) - { - return ((!TESTBIT(mask, IsIdentified))); - } - - // fill the histograms of each particle types - void fillHistograms(const McMuons::iterator& muon) - { - const auto mask(getMask(muon)); - const auto pt(muon.pt()), eta(muon.eta()); - - if (isIdentified(mask)) { - registry.fill(HIST("h2Identified"), pt, eta); - } - if (isMuon(mask)) { - registry.fill(HIST("h2Muon"), pt, eta); - } - if (isSecondaryMu(mask)) { - registry.fill(HIST("h2SecondaryMu"), pt, eta); - } - if (isLightDecayMu(mask)) { - registry.fill(HIST("h2LightDecayMu"), pt, eta); - } - if (isTauDecayMu(mask)) { - registry.fill(HIST("h2TauDecayMu"), pt, eta); - } - if (isWBosonDecayMu(mask)) { - registry.fill(HIST("h2WBosonDecayMu"), pt, eta); - } - if (isZBosonDecayMu(mask)) { - registry.fill(HIST("h2ZBosonDecayMu"), pt, eta); - } - if (isQuarkoniumDecayMu(mask)) { - registry.fill(HIST("h2QuarkoniumDecayMu"), pt, eta); - } - if (isBeautyMu(mask)) { - registry.fill(HIST("h2BeautyMu"), pt, eta); - } - if (isBeautyDecayMu(mask)) { - registry.fill(HIST("h2BeautyDecayMu"), pt, eta); - } - if (isNonpromptCharmMu(mask)) { - registry.fill(HIST("h2NonpromptCharmMu"), pt, eta); - } - if (isPromptCharmMu(mask)) { - registry.fill(HIST("h2PromptCharmMu"), pt, eta); - } - if (isOtherMu(mask)) { - registry.fill(HIST("h2OtherMu"), pt, eta); - } - if (isHadron(mask)) { - registry.fill(HIST("h2Hadron"), pt, eta); - } - if (isUnidentified(mask)) { - registry.fill(HIST("h2Unidentified"), pt, eta); - } - } - - void process(McGenCollisions::iterator const& mccollision, McMuons const& muons, aod::McParticles const&, McRecCollisions const& collisions) - { - - // event selections - if (std::abs(mccollision.posZ()) > zVtxMax) { - return; - } - - registry.fill(HIST("hNEventGenMu"), 1); - - for (const auto& muon : muons) { - if (!(muon.has_mcParticle())) { - continue; - } - auto mcPart(muon.mcParticle()); - auto pdgGen(mcPart.pdgCode()); - auto etaGen(mcPart.eta()); - - if (!(std::abs(pdgGen) == kMuonMinus)) { - continue; - } - if ((etaGen >= etaMax) || (etaGen < etaMin)) { - continue; - } - registry.fill(HIST("hGenMuVar"), pdgGen, mcPart.pt(), etaGen); - } - - for (const auto& collision : collisions) { - if (std::abs(collision.posZ()) > zVtxMax) { - continue; - } - registry.fill(HIST("hNEventRecMu"), 1); - - for (const auto& muon : muons) { - // muon selections - registry.fill(HIST("hMcMask"), muon.mcMask()); - - if (muon.mcMask() != mcMaskSelection) { - continue; - } - - if (!(muon.has_mcParticle())) { - continue; - } - const auto pt(muon.pt()), eta(muon.eta()), rAbsorb(muon.rAtAbsorberEnd()), pDca(muon.pDca()), chi2(muon.chi2MatchMCHMFT()); - const auto dcaXY{RecoDecay::sqrtSumOfSquares(muon.fwdDcaX(), muon.fwdDcaY())}; - const auto muTrackType{muon.trackType()}; - const auto mcLabel(muon.mcParticleId()); - - if (mcLabel < 0) { - continue; - } - - registry.fill(HIST("hMuMcLabel"), mcLabel); - registry.fill(HIST("hMuTrackType"), muTrackType); - - auto mcparticle(muon.mcParticle()); - const auto pdg(mcparticle.pdgCode()); - - if ((eta >= etaMax) || (eta < etaMin)) { - continue; - } - if ((rAbsorb >= rAbsorbMax) || (rAbsorb < rAbsorbMin)) { - continue; - } - if (pDca >= pDcaMax) { - continue; - } - registry.fill(HIST("hRecMuVar"), pdg, pt, eta); - registry.fill(HIST("hMuAfterAccCuts"), pdg, pt, eta, rAbsorb, dcaXY, pDca, chi2, muTrackType); - - fillHistograms(muon); - } - } - } - - void processResTrack(McGenCollisions::iterator const& mccollision, McRecCollisions const& collisions, aod::McParticles const& particles, MyTracks const& tracks) - { - // event selections - if (std::abs(mccollision.posZ()) > zVtxMax) { - return; - } - registry.fill(HIST("hNEventGen"), 1.); - auto nP = 0; - for (const auto& particle : particles) { - if (!particle.isPhysicalPrimary()) { - continue; - } - if (!particle.producedByGenerator()) { - continue; - } - - auto charge = 0.; - auto* p = pdg->GetParticle(particle.pdgCode()); - if (p != nullptr) { - charge = p->Charge(); - } - - if (std::abs(charge) < MinCharge) { - continue; - } - if (particle.pt() < ptTrackMin || std::abs(particle.eta()) >= etaTrackMax) { - continue; - } - - registry.fill(HIST("hParticleGen"), particle.pt(), particle.eta()); - nP++; - } - for (const auto& collision : collisions) { - if (std::abs(collision.posZ()) > zVtxMax) { - continue; - } - registry.fill(HIST("hNEventRec"), 1.); - auto nTrk = 0; - auto tracksample = tracks.sliceBy(perCol, collision.globalIndex()); - for (const auto& track : tracksample) { - if (!track.isGlobalTrack()) - continue; - registry.fill(HIST("hParticleRec"), track.pt(), track.eta()); - ++nTrk; - } - if (nTrk < 1) - continue; - registry.fill(HIST("hTrackResponse"), nP, nTrk); - } - } - PROCESS_SWITCH(HfTaskSingleMuonMultMc, processResTrack, "Process Track Reconstruction/Generation", true); -}; - -WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) -{ - return WorkflowSpec{ - adaptAnalysisTask(cfgc), - }; -}