|
| 1 | +// Copyright 2019-2020 CERN and copyright holders of ALICE O2. |
| 2 | +// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. |
| 3 | +// All rights not expressly granted are reserved. |
| 4 | +// |
| 5 | +// This software is distributed under the terms of the GNU General Public |
| 6 | +// License v3 (GPL Version 3), copied verbatim in the file "COPYING". |
| 7 | +// |
| 8 | +// In applying this license CERN does not waive the privileges and immunities |
| 9 | +// granted to it by virtue of its status as an Intergovernmental Organization |
| 10 | +// or submit itself to any jurisdiction. |
| 11 | + |
| 12 | +/// \file taskSingleMuonMult.cxx |
| 13 | +/// \brief Task used to study the Open heavy flavour decay muon production as a function of multiplicity. |
| 14 | +/// \author Md Samsul Islam <md.samsul.islam@cern.ch>, IITB |
| 15 | + |
| 16 | +#include <cmath> |
| 17 | + |
| 18 | +#include "CommonConstants/MathConstants.h" |
| 19 | +#include "Framework/AnalysisDataModel.h" |
| 20 | +#include "Framework/AnalysisTask.h" |
| 21 | +#include "Framework/HistogramRegistry.h" |
| 22 | +#include "Framework/runDataProcessing.h" |
| 23 | +#include "ReconstructionDataFormats/TrackFwd.h" |
| 24 | + |
| 25 | +#include "Common/Core/TrackSelection.h" |
| 26 | +#include "Common/Core/trackUtilities.h" |
| 27 | +#include "Common/DataModel/Centrality.h" |
| 28 | +#include "Common/DataModel/EventSelection.h" |
| 29 | +#include "Common/DataModel/Multiplicity.h" |
| 30 | +#include "Common/DataModel/TrackSelectionTables.h" |
| 31 | + |
| 32 | +using namespace o2; |
| 33 | +using namespace o2::aod; |
| 34 | +using namespace o2::framework; |
| 35 | +using namespace o2::framework::expressions; |
| 36 | +using namespace o2::aod::fwdtrack; |
| 37 | + |
| 38 | +struct HfTaskSingleMuonMult { |
| 39 | + |
| 40 | + // enum for event selection bins |
| 41 | + enum EventSelection { |
| 42 | + AllEvents = 0, |
| 43 | + Sel8, |
| 44 | + VtxZAfterSel, |
| 45 | + NEventSelection |
| 46 | + }; |
| 47 | + |
| 48 | + // enum for muon track selection bins |
| 49 | + enum MuonSelection { |
| 50 | + NoCut = 0, |
| 51 | + EtaCut, |
| 52 | + RAbsorbCut, |
| 53 | + PDcaCut, |
| 54 | + Chi2Cut, |
| 55 | + NMuonSelection |
| 56 | + }; |
| 57 | + |
| 58 | + Configurable<float> zVtxMax{"zVtxMax", 10., "maxium z of primary vertex [cm]"}; |
| 59 | + Configurable<float> ptTrackMin{"ptTrackMin", 0.15, "minimum pt of tracks"}; |
| 60 | + Configurable<float> etaTrackMax{"etaTrackMax", 0.8, "maximum pseudorapidity of tracks"}; |
| 61 | + Configurable<float> etaMin{"etaMin", -3.6, "minimum pseudorapidity"}; |
| 62 | + Configurable<float> etaMax{"etaMax", -2.5, "maximum pseudorapidity"}; |
| 63 | + Configurable<float> pDcaMin{"pDcaMin", 324., "p*DCA value for small RAbsorb"}; |
| 64 | + Configurable<float> pDcaMax{"pDcaMax", 594., "p*DCA value for large RAbsorb"}; |
| 65 | + Configurable<float> rAbsorbMin{"rAbsorbMin", 17.6, "R at absorber end minimum value"}; |
| 66 | + Configurable<float> rAbsorbMax{"rAbsorbMax", 89.5, "R at absorber end maximum value"}; |
| 67 | + Configurable<float> rAbsorbMid{"rAbsorbMid", 26.5, "R at absorber end split point for different p*DCA selections"}; |
| 68 | + Configurable<bool> reduceOrphMft{"reduceOrphMft", true, "reduce orphan MFT tracks"}; |
| 69 | + |
| 70 | + using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::Mults, aod::CentFT0Ms>; |
| 71 | + using MyMuons = soa::Join<aod::FwdTracks, aod::FwdTracksDCA>; |
| 72 | + using MyMcMuons = soa::Join<aod::FwdTracks, aod::McFwdTrackLabels, aod::FwdTracksDCA>; |
| 73 | + using MyTracks = soa::Filtered<soa::Join<aod::FullTracks, aod::TracksIU, aod::TracksDCA, aod::TrackSelection>>; |
| 74 | + |
| 75 | + // Filter Global Track for Multiplicty |
| 76 | + Filter trackFilter = ((nabs(aod::track::eta) < etaTrackMax) && (aod::track::pt > ptTrackMin)); |
| 77 | + |
| 78 | + // Number the types of muon tracks |
| 79 | + static constexpr uint8_t NTrackTypes{ForwardTrackTypeEnum::MCHStandaloneTrack + 1}; |
| 80 | + |
| 81 | + HistogramRegistry registry{"registry"}; |
| 82 | + |
| 83 | + void init(InitContext&) |
| 84 | + { |
| 85 | + AxisSpec axisCent = {101, -0.5, 100.5, "centrality"}; |
| 86 | + AxisSpec axisEvent{NEventSelection, 0, NEventSelection, "Event Selection"}; |
| 87 | + AxisSpec axisVtxZ{80, -20., 20., "#it{z}_{vtx} (cm)"}; |
| 88 | + AxisSpec axisMuon{NMuonSelection, 0, NMuonSelection, "Muon Selection"}; |
| 89 | + AxisSpec axisNCh{500, 0.5, 500.5, "#it{N}_{ch}"}; |
| 90 | + AxisSpec axisNMu{20, -0.5, 19.5, "#it{N}_{#mu}"}; |
| 91 | + AxisSpec axisPt{1000, 0., 500., "#it{p}_{T} (GeV/#it{c})"}; |
| 92 | + AxisSpec axisEta{250, -5., 5., "#it{#eta}"}; |
| 93 | + AxisSpec axisTheta{500, 170., 180., "#it{#theta}"}; |
| 94 | + AxisSpec axisRAbsorb{1000, 0., 100., "#it{R}_{Absorb} (cm)"}; |
| 95 | + AxisSpec axisDCA{500, 0., 5., "#it{DCA}_{xy} (cm)"}; |
| 96 | + AxisSpec axisChi2MatchMCHMFT{1000, 0., 1000., "MCH-MFT matching #chi^{2}"}; |
| 97 | + AxisSpec axisSign{5, -2.5, 2.5, "Charge"}; |
| 98 | + AxisSpec axisPDca{100000, 0, 100000, "#it{p} #times DCA (GeV/#it{c} * cm)"}; |
| 99 | + AxisSpec axisDCAx{1000, -5., 5., "#it{DCA}_{x or y} (cm)"}; |
| 100 | + AxisSpec axisEtaDif{200, -2., 2., "#it{#eta} diff"}; |
| 101 | + AxisSpec axisDeltaPt{10000, -50, 50, "#Delta #it{p}_{T} (GeV/#it{c})"}; |
| 102 | + AxisSpec axisTrackType{8, -1.5, 6.5, "TrackType"}; |
| 103 | + AxisSpec axisPtDif{200, -2., 2., "#it{p}_{T} diff (GeV/#it{c})"}; |
| 104 | + |
| 105 | + registry.add("hCentrality", "Centrality Percentile", {HistType::kTH1F, {axisCent}}); |
| 106 | + registry.add("hEventSel", " Number of Events", {HistType::kTH1F, {axisEvent}}); |
| 107 | + registry.add("hNch", "Charged Particle Multiplicity", {HistType::kTH1F, {axisNCh}}); |
| 108 | + registry.add("hVtxZBeforeSel", "Z-vertex distribution before zVtx Cut", {HistType::kTH1F, {axisVtxZ}}); |
| 109 | + registry.add("hVtxZAfterSel", "Z-vertex distribution after zVtx Cut", {HistType::kTH1F, {axisVtxZ}}); |
| 110 | + |
| 111 | + registry.add("hMuonSel", "Selection of muon tracks at various kinematic cuts", {HistType::kTH1F, {axisMuon}}); |
| 112 | + registry.add("hMuBeforeMatchMFT", "Muon information before any Kinemeatic cuts applied", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); |
| 113 | + registry.add("hMuBeforeAccCuts", "Muon information before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); |
| 114 | + registry.add("h3DCABeforeAccCuts", "DCAx,DCAy,DCAz information before Acceptance cuts", {HistType::kTH3F, {axisDCAx, axisDCAx, axisTrackType}}); |
| 115 | + registry.add("hMuDeltaPtBeforeAccCuts", "Muon information with DeltaPt before applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisDeltaPt}, 10}); |
| 116 | + registry.add("hMuAfterEtaCuts", "Muon information after applying Eta cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); |
| 117 | + registry.add("hMuAfterRAbsorbCuts", "Muon information after applying RAbsorb cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); |
| 118 | + registry.add("hMuAfterPdcaCuts", "Muon information after applying Pdca cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); |
| 119 | + registry.add("hMuAfterAccCuts", "Muon information after applying all Kinematic cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisTrackType}, 10}); |
| 120 | + registry.add("h3DCAAfterAccCuts", "DCAx,DCAy,DCAz information after Acceptance cuts", {HistType::kTH3F, {axisDCAx, axisDCAx, axisTrackType}}); |
| 121 | + registry.add("hMuDeltaPtAfterAccCuts", "Muon information with DeltaPt after applying Acceptance cuts", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisTheta, axisRAbsorb, axisDCA, axisPDca, axisChi2MatchMCHMFT, axisDeltaPt}, 10}); |
| 122 | + |
| 123 | + registry.add("hTHnTrk", "Muon information with multiplicity", {HistType::kTHnSparseF, {axisCent, axisNCh, axisPt, axisEta, axisSign}, 5}); |
| 124 | + registry.add("h3MultNchNmu", "Number of muons and multiplicity", {HistType::kTH3F, {axisCent, axisNCh, axisNMu}}); |
| 125 | + registry.add("hMultNchNmuTrackType", "Number of muons with different types and multiplicity", {HistType::kTHnSparseF, {axisCent, axisNCh, axisNMu, axisTrackType}, 4}); |
| 126 | + |
| 127 | + auto hEvstat = registry.get<TH1>(HIST("hEventSel")); |
| 128 | + auto* xEv = hEvstat->GetXaxis(); |
| 129 | + xEv->SetBinLabel(AllEvents + 1, "All events"); |
| 130 | + xEv->SetBinLabel(Sel8 + 1, "sel8"); |
| 131 | + xEv->SetBinLabel(VtxZAfterSel + 1, "VtxZAfterSel"); |
| 132 | + |
| 133 | + auto hMustat = registry.get<TH1>(HIST("hMuonSel")); |
| 134 | + auto* xMu = hMustat->GetXaxis(); |
| 135 | + xMu->SetBinLabel(NoCut + 1, "noCut"); |
| 136 | + xMu->SetBinLabel(EtaCut + 1, "etaCut"); |
| 137 | + xMu->SetBinLabel(RAbsorbCut + 1, "RAbsorbCut"); |
| 138 | + xMu->SetBinLabel(PDcaCut + 1, "pDcaCut"); |
| 139 | + xMu->SetBinLabel(Chi2Cut + 1, "chi2Cut"); |
| 140 | + } |
| 141 | + |
| 142 | + void process(MyCollisions::iterator const& collision, |
| 143 | + MyTracks const& tracks, |
| 144 | + MyMuons const& muons) |
| 145 | + { |
| 146 | + registry.fill(HIST("hEventSel"), AllEvents); |
| 147 | + |
| 148 | + if (!collision.sel8()) { |
| 149 | + return; |
| 150 | + } |
| 151 | + registry.fill(HIST("hEventSel"), Sel8); |
| 152 | + registry.fill(HIST("hVtxZBeforeSel"), collision.posZ()); |
| 153 | + |
| 154 | + if (std::abs(collision.posZ()) > zVtxMax) { |
| 155 | + return; |
| 156 | + } |
| 157 | + registry.fill(HIST("hEventSel"), VtxZAfterSel); |
| 158 | + registry.fill(HIST("hVtxZAfterSel"), collision.posZ()); |
| 159 | + |
| 160 | + // T0M centrality |
| 161 | + const auto cent = collision.centFT0M(); |
| 162 | + registry.fill(HIST("hCentrality"), cent); |
| 163 | + |
| 164 | + // Charged particles |
| 165 | + for (const auto& track : tracks) { |
| 166 | + if (!track.isGlobalTrack()) { |
| 167 | + continue; |
| 168 | + } |
| 169 | + } |
| 170 | + |
| 171 | + auto nCh{tracks.size()}; |
| 172 | + if (nCh < 1) { |
| 173 | + return; |
| 174 | + } |
| 175 | + registry.fill(HIST("hNch"), nCh); |
| 176 | + |
| 177 | + for (const auto& track : tracks) { |
| 178 | + registry.fill(HIST("hTHnTrk"), cent, nCh, track.pt(), track.eta(), track.sign()); |
| 179 | + } |
| 180 | + |
| 181 | + // muons per event |
| 182 | + int nMu{0}; |
| 183 | + int nMuType[NTrackTypes] = {0}; |
| 184 | + |
| 185 | + for (const auto& muon : muons) { |
| 186 | + 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()}; |
| 187 | + const auto dcaXY{RecoDecay::sqrtSumOfSquares(muon.fwdDcaX(), muon.fwdDcaY())}; |
| 188 | + const auto muTrackType{muon.trackType()}; |
| 189 | + |
| 190 | + registry.fill(HIST("hMuBeforeMatchMFT"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); |
| 191 | + |
| 192 | + // histograms before the acceptance cuts |
| 193 | + registry.fill(HIST("hMuonSel"), NoCut); |
| 194 | + registry.fill(HIST("hMuBeforeAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); |
| 195 | + registry.fill(HIST("h3DCABeforeAccCuts"), muon.fwdDcaX(), muon.fwdDcaY(), muTrackType); |
| 196 | + |
| 197 | + if (muon.has_matchMCHTrack()) { |
| 198 | + auto muonType3 = muon.template matchMCHTrack_as<MyMuons>(); |
| 199 | + auto dpt = muonType3.pt() - pt; |
| 200 | + if (muTrackType == ForwardTrackTypeEnum::GlobalMuonTrack) { |
| 201 | + registry.fill(HIST("hMuDeltaPtBeforeAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, dpt); |
| 202 | + } |
| 203 | + } |
| 204 | + |
| 205 | + // Apply various standard muon acceptance cuts |
| 206 | + // eta cuts |
| 207 | + if ((eta >= etaMax) || (eta < etaMin)) { |
| 208 | + continue; |
| 209 | + } |
| 210 | + registry.fill(HIST("hMuonSel"), EtaCut); |
| 211 | + registry.fill(HIST("hMuAfterEtaCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); |
| 212 | + |
| 213 | + // Rabsorb cuts |
| 214 | + if ((rAbsorb < rAbsorbMin) || (rAbsorb >= rAbsorbMax)) { |
| 215 | + continue; |
| 216 | + } |
| 217 | + registry.fill(HIST("hMuonSel"), RAbsorbCut); |
| 218 | + registry.fill(HIST("hMuAfterRAbsorbCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); |
| 219 | + |
| 220 | + if ((rAbsorb < rAbsorbMid) && (pDca >= pDcaMin)) { |
| 221 | + continue; |
| 222 | + } |
| 223 | + if ((rAbsorb >= rAbsorbMid) && (pDca >= pDcaMax)) { |
| 224 | + continue; |
| 225 | + } |
| 226 | + registry.fill(HIST("hMuonSel"), PDcaCut); |
| 227 | + registry.fill(HIST("hMuAfterPdcaCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); |
| 228 | + |
| 229 | + // MCH-MFT matching chi2 |
| 230 | + if (muon.chi2() >= 1e6) { |
| 231 | + continue; |
| 232 | + } |
| 233 | + registry.fill(HIST("hMuonSel"), Chi2Cut); |
| 234 | + |
| 235 | + // histograms after acceptance cuts |
| 236 | + registry.fill(HIST("hMuAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, muTrackType); |
| 237 | + registry.fill(HIST("h3DCAAfterAccCuts"), muon.fwdDcaX(), muon.fwdDcaY(), muTrackType); |
| 238 | + nMu++; |
| 239 | + nMuType[muTrackType]++; |
| 240 | + |
| 241 | + if (muon.has_matchMCHTrack()) { |
| 242 | + auto muonType3 = muon.template matchMCHTrack_as<MyMuons>(); |
| 243 | + auto dpt = muonType3.pt() - pt; |
| 244 | + |
| 245 | + if (muTrackType == ForwardTrackTypeEnum::GlobalMuonTrack) { |
| 246 | + registry.fill(HIST("hMuDeltaPtAfterAccCuts"), cent, nCh, pt, eta, theta, rAbsorb, dcaXY, pDca, chi2, dpt); |
| 247 | + } |
| 248 | + } |
| 249 | + } |
| 250 | + |
| 251 | + registry.fill(HIST("h3MultNchNmu"), cent, nCh, nMu); |
| 252 | + |
| 253 | + // Fill number of muons of various types with multiplicity |
| 254 | + for (auto indexType{0u}; indexType < NTrackTypes; ++indexType) { |
| 255 | + if (nMuType[indexType] > 0) { |
| 256 | + registry.fill(HIST("hMultNchNmuTrackType"), cent, nCh, nMuType[indexType], indexType); |
| 257 | + } |
| 258 | + } |
| 259 | + } |
| 260 | +}; |
| 261 | + |
| 262 | +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) |
| 263 | +{ |
| 264 | + return WorkflowSpec{adaptAnalysisTask<HfTaskSingleMuonMult>(cfgc)}; |
| 265 | +} |
0 commit comments