|
| 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 flowEfficiencyCasc.cxx |
| 13 | +/// \author Fuchun Cui(fcui@cern.ch) |
| 14 | +/// \since Feb/21/2025 |
| 15 | +/// \brief This task is to calculate V0s and cascades local density efficiency |
| 16 | + |
| 17 | +#include <vector> |
| 18 | +#include "Common/DataModel/Centrality.h" |
| 19 | +#include "Common/DataModel/Multiplicity.h" |
| 20 | +#include "Common/DataModel/TrackSelectionTables.h" |
| 21 | +#include "Common/DataModel/EventSelection.h" |
| 22 | +#include "Framework/runDataProcessing.h" |
| 23 | +#include "Framework/AnalysisTask.h" |
| 24 | +#include "Framework/ASoAHelpers.h" |
| 25 | +#include "Common/Core/TrackSelection.h" |
| 26 | +#include "Common/Core/TrackSelectionDefaults.h" |
| 27 | +#include "Common/DataModel/PIDResponse.h" |
| 28 | +#include "PWGLF/DataModel/cascqaanalysis.h" |
| 29 | +#include "PWGLF/DataModel/LFStrangenessTables.h" |
| 30 | +#include "PWGLF/DataModel/LFStrangenessPIDTables.h" |
| 31 | +#include "CommonConstants/PhysicsConstants.h" |
| 32 | +#include <TPDGCode.h> |
| 33 | + |
| 34 | +using namespace o2; |
| 35 | +using namespace o2::framework; |
| 36 | +using namespace o2::framework::expressions; |
| 37 | + |
| 38 | +#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable<TYPE> NAME{#NAME, DEFAULT, HELP}; |
| 39 | + |
| 40 | +struct FlowEfficiencyCasc { |
| 41 | + O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range") |
| 42 | + O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "Minimal pT for tracks") |
| 43 | + O2_DEFINE_CONFIGURABLE(cfgCutPtMax, float, 3.0f, "Maximal pT for tracks") |
| 44 | + O2_DEFINE_CONFIGURABLE(cfgCutEta, float, 0.8f, "Eta range for tracks") |
| 45 | + O2_DEFINE_CONFIGURABLE(cfgCutChi2prTPCcls, float, 2.5f, "max chi2 per TPC clusters") |
| 46 | + // topological cut for V0 |
| 47 | + O2_DEFINE_CONFIGURABLE(cfgv0_radius, float, 5.0f, "minimum decay radius") |
| 48 | + O2_DEFINE_CONFIGURABLE(cfgv0_v0cospa, float, 0.995f, "minimum cosine of pointing angle") |
| 49 | + O2_DEFINE_CONFIGURABLE(cfgv0_dcadautopv, float, 0.1f, "minimum daughter DCA to PV") |
| 50 | + O2_DEFINE_CONFIGURABLE(cfgv0_dcav0dau, float, 0.5f, "maximum DCA among V0 daughters") |
| 51 | + O2_DEFINE_CONFIGURABLE(cfgv0_mk0swindow, float, 0.1f, "Invariant mass window of K0s") |
| 52 | + O2_DEFINE_CONFIGURABLE(cfgv0_mlambdawindow, float, 0.04f, "Invariant mass window of lambda") |
| 53 | + O2_DEFINE_CONFIGURABLE(cfgv0_ArmPodocut, float, 0.2f, "Armenteros Podolski cut for K0") |
| 54 | + // topological cut for cascade |
| 55 | + O2_DEFINE_CONFIGURABLE(cfgcasc_radius, float, 0.5f, "minimum decay radius") |
| 56 | + O2_DEFINE_CONFIGURABLE(cfgcasc_casccospa, float, 0.999f, "minimum cosine of pointing angle") |
| 57 | + O2_DEFINE_CONFIGURABLE(cfgcasc_v0cospa, float, 0.998f, "minimum cosine of pointing angle") |
| 58 | + O2_DEFINE_CONFIGURABLE(cfgcasc_dcav0topv, float, 0.01f, "minimum daughter DCA to PV") |
| 59 | + O2_DEFINE_CONFIGURABLE(cfgcasc_dcabachtopv, float, 0.01f, "minimum bachelor DCA to PV") |
| 60 | + O2_DEFINE_CONFIGURABLE(cfgcasc_dcacascdau, float, 0.3f, "maximum DCA among cascade daughters") |
| 61 | + O2_DEFINE_CONFIGURABLE(cfgcasc_dcav0dau, float, 1.0f, "maximum DCA among V0 daughters") |
| 62 | + O2_DEFINE_CONFIGURABLE(cfgcasc_mlambdawindow, float, 0.04f, "Invariant mass window of lambda") |
| 63 | + // track quality and type selections |
| 64 | + O2_DEFINE_CONFIGURABLE(cfgtpcclusters, int, 70, "minimum number of TPC clusters requirement") |
| 65 | + O2_DEFINE_CONFIGURABLE(cfgitsclusters, int, 1, "minimum number of ITS clusters requirement") |
| 66 | + O2_DEFINE_CONFIGURABLE(cfgtpcclufindable, int, 1, "minimum number of findable TPC clusters") |
| 67 | + O2_DEFINE_CONFIGURABLE(cfgtpccrossoverfindable, int, 1, "minimum number of Ratio crossed rows over findable clusters") |
| 68 | + O2_DEFINE_CONFIGURABLE(cfgcheckDauTPC, bool, true, "check daughter tracks TPC or not") |
| 69 | + O2_DEFINE_CONFIGURABLE(cfgcheckDauTOF, bool, false, "check daughter tracks TOF or not") |
| 70 | + O2_DEFINE_CONFIGURABLE(cfgCasc_rapidity, float, 0.5, "rapidity") |
| 71 | + |
| 72 | + O2_DEFINE_CONFIGURABLE(cfgNSigmatpctof, std::vector<float>, (std::vector<float>{3, 3, 3}), "tpc and tof NSigma for Pion Kaon Proton") |
| 73 | + |
| 74 | + ConfigurableAxis cfgaxisPt{"cfgaxisPt", {VARIABLE_WIDTH, 0.20, 0.25, 0.30, 0.35, 0.40, 0.45, 0.50, 0.55, 0.60, 0.65, 0.70, 0.75, 0.80, 0.85, 0.90, 0.95, 1.00, 1.10, 1.20, 1.30, 1.40, 1.50, 1.60, 1.70, 1.80, 1.90, 2.00, 2.20, 2.40, 2.60, 2.80, 3.00, 3.50, 4.00, 4.50, 5.00, 5.50, 6.00, 10.0}, "pt (GeV)"}; |
| 75 | + ConfigurableAxis cfgaxisPtXi{"cfgaxisPtXi", {VARIABLE_WIDTH, 0, 0.1, 0.5, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1, 2.3, 2.5, 2.7, 2.9, 3.9, 4.9, 5.9, 9.9}, "pt (GeV)"}; |
| 76 | + ConfigurableAxis cfgaxisPtOmega{"cfgaxisPtOmega", {VARIABLE_WIDTH, 0, 0.1, 0.5, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1, 2.3, 2.5, 2.7, 2.9, 3.9, 4.9, 5.9, 9.9}, "pt (GeV)"}; |
| 77 | + ConfigurableAxis cfgaxisPtV0{"cfgaxisPtV0", {VARIABLE_WIDTH, 0, 0.1, 0.5, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1, 2.3, 2.5, 2.7, 2.9, 3.9, 4.9, 5.9, 9.9}, "pt (GeV)"}; |
| 78 | + ConfigurableAxis cfgaxisMultiplicity{"cfgaxisMultiplicity", {1000, 0, 5000}, "Nch"}; |
| 79 | + |
| 80 | + using MyCollisions = soa::Join<aod::StraCollisions, aod::StraEvSels>; |
| 81 | + using MyMcCollisions = soa::Join<aod::StraMCCollisions, aod::StraMCCollMults>; |
| 82 | + using CascMCCandidates = soa::Join<aod::CascCollRefs, aod::CascCores, aod::CascExtras, aod::CascBBs, aod::CascCoreMCLabels>; |
| 83 | + using V0MCCandidates = soa::Join<aod::V0CollRefs, aod::V0Cores, aod::V0Extras, aod::V0CoreMCLabels>; |
| 84 | + using DaughterTracks = soa::Join<aod::DauTrackExtras, aod::DauTrackTPCPIDs>; |
| 85 | + |
| 86 | + // Define the output |
| 87 | + HistogramRegistry registry{"registry"}; |
| 88 | + |
| 89 | + std::vector<float> cfgNSigma = cfgNSigmatpctof; |
| 90 | + |
| 91 | + void init(InitContext const&) |
| 92 | + { |
| 93 | + const AxisSpec axisCounter{1, 0, +1, ""}; |
| 94 | + // create histograms |
| 95 | + registry.add("eventCounter", "eventCounter", kTH1F, {axisCounter}); |
| 96 | + registry.add("mcEventCounter", "Monte Carlo Truth EventCounter", kTH1F, {axisCounter}); |
| 97 | + |
| 98 | + registry.add("h2DGenK0s", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}}); |
| 99 | + registry.add("h2DGenLambda", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}}); |
| 100 | + registry.add("h2DGenXi", "", {HistType::kTH2D, {cfgaxisPtXi, cfgaxisMultiplicity}}); |
| 101 | + registry.add("h2DGenOmega", "", {HistType::kTH2D, {cfgaxisPtOmega, cfgaxisMultiplicity}}); |
| 102 | + registry.add("h2DRecK0s", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}}); |
| 103 | + registry.add("h2DRecLambda", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}}); |
| 104 | + registry.add("h2DRecXi", "", {HistType::kTH2D, {cfgaxisPtXi, cfgaxisMultiplicity}}); |
| 105 | + registry.add("h2DRecOmega", "", {HistType::kTH2D, {cfgaxisPtOmega, cfgaxisMultiplicity}}); |
| 106 | + } |
| 107 | + |
| 108 | + void processRec(MyCollisions::iterator const& collision, V0MCCandidates const& V0s, CascMCCandidates const& Cascades, DaughterTracks const&, soa::Join<aod::CascMCCores, aod::CascMCCollRefs> const&, soa::Join<aod::V0MCCores, aod::V0MCCollRefs> const&) |
| 109 | + { |
| 110 | + registry.fill(HIST("eventCounter"), 0.5); |
| 111 | + if (!collision.sel8()) |
| 112 | + return; |
| 113 | + int rectracknum = collision.multNTracksGlobal(); |
| 114 | + for (const auto& casc : Cascades) { |
| 115 | + if (!casc.has_cascMCCore()) |
| 116 | + continue; |
| 117 | + auto negdau = casc.negTrackExtra_as<DaughterTracks>(); |
| 118 | + auto posdau = casc.posTrackExtra_as<DaughterTracks>(); |
| 119 | + auto bachelor = casc.bachTrackExtra_as<DaughterTracks>(); |
| 120 | + // track quality check |
| 121 | + if (bachelor.tpcNClsFound() < cfgtpcclusters) |
| 122 | + continue; |
| 123 | + if (posdau.tpcNClsFound() < cfgtpcclusters) |
| 124 | + continue; |
| 125 | + if (negdau.tpcNClsFound() < cfgtpcclusters) |
| 126 | + continue; |
| 127 | + if (bachelor.itsNCls() < cfgitsclusters) |
| 128 | + continue; |
| 129 | + if (posdau.itsNCls() < cfgitsclusters) |
| 130 | + continue; |
| 131 | + if (negdau.itsNCls() < cfgitsclusters) |
| 132 | + continue; |
| 133 | + // topological cut |
| 134 | + if (casc.cascradius() < cfgcasc_radius) |
| 135 | + continue; |
| 136 | + if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cfgcasc_casccospa) |
| 137 | + continue; |
| 138 | + if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cfgcasc_v0cospa) |
| 139 | + continue; |
| 140 | + if (std::fabs(casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ())) < cfgcasc_dcav0topv) |
| 141 | + continue; |
| 142 | + if (std::fabs(casc.dcabachtopv()) < cfgcasc_dcabachtopv) |
| 143 | + continue; |
| 144 | + if (casc.dcacascdaughters() > cfgcasc_dcacascdau) |
| 145 | + continue; |
| 146 | + if (casc.dcaV0daughters() > cfgcasc_dcav0dau) |
| 147 | + continue; |
| 148 | + if (std::fabs(casc.mLambda() - o2::constants::physics::MassLambda0) > cfgcasc_mlambdawindow) |
| 149 | + continue; |
| 150 | + // Omega and antiOmega |
| 151 | + if (casc.sign() < 0 && (casc.mOmega() > 1.63) && (casc.mOmega() < 1.71) && std::fabs(casc.yOmega()) < cfgCasc_rapidity && |
| 152 | + (!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaKa()) < cfgNSigma[2] && std::fabs(posdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(negdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 153 | + registry.fill(HIST("h2DRecOmega"), casc.pt(), rectracknum); |
| 154 | + } else if (casc.sign() < 0 && (casc.mOmega() > 1.63) && (casc.mOmega() < 1.71) && std::fabs(casc.yOmega()) < cfgCasc_rapidity && |
| 155 | + (!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaKa()) < cfgNSigma[2] && std::fabs(negdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(posdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 156 | + registry.fill(HIST("h2DRecOmega"), casc.pt(), rectracknum); |
| 157 | + } |
| 158 | + // Xi and antiXi |
| 159 | + if (casc.sign() < 0 && (casc.mXi() > 1.30) && (casc.mXi() < 1.37) && std::fabs(casc.yXi()) < cfgCasc_rapidity && |
| 160 | + (!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaPi()) < cfgNSigma[0] && std::fabs(posdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(negdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 161 | + registry.fill(HIST("h2DRecXi"), casc.pt(), rectracknum); |
| 162 | + } else if (casc.sign() < 0 && (casc.mXi() > 1.30) && (casc.mXi() < 1.37) && std::fabs(casc.yXi()) < cfgCasc_rapidity && |
| 163 | + (!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaPi()) < cfgNSigma[0] && std::fabs(negdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(posdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 164 | + registry.fill(HIST("h2DRecXi"), casc.pt(), rectracknum); |
| 165 | + } |
| 166 | + } |
| 167 | + |
| 168 | + for (const auto& v0 : V0s) { |
| 169 | + if (!v0.has_v0MCCore()) |
| 170 | + continue; |
| 171 | + auto v0negdau = v0.negTrackExtra_as<DaughterTracks>(); |
| 172 | + auto v0posdau = v0.posTrackExtra_as<DaughterTracks>(); |
| 173 | + |
| 174 | + // track quality check |
| 175 | + if (v0posdau.tpcNClsFound() < cfgtpcclusters) |
| 176 | + continue; |
| 177 | + if (v0negdau.tpcNClsFound() < cfgtpcclusters) |
| 178 | + continue; |
| 179 | + if (v0posdau.tpcNClsFindable() < cfgtpcclufindable) |
| 180 | + continue; |
| 181 | + if (v0negdau.tpcNClsFindable() < cfgtpcclufindable) |
| 182 | + continue; |
| 183 | + if (v0posdau.tpcCrossedRowsOverFindableCls() < cfgtpccrossoverfindable) |
| 184 | + continue; |
| 185 | + if (v0posdau.itsNCls() < cfgitsclusters) |
| 186 | + continue; |
| 187 | + if (v0negdau.itsNCls() < cfgitsclusters) |
| 188 | + continue; |
| 189 | + // topological cut |
| 190 | + if (v0.v0radius() < cfgv0_radius) |
| 191 | + continue; |
| 192 | + if (v0.v0cosPA() < cfgv0_v0cospa) |
| 193 | + continue; |
| 194 | + if (v0.dcaV0daughters() > cfgv0_dcav0dau) |
| 195 | + continue; |
| 196 | + if (std::fabs(v0.dcapostopv()) < cfgv0_dcadautopv) |
| 197 | + continue; |
| 198 | + if (std::fabs(v0.dcanegtopv()) < cfgv0_dcadautopv) |
| 199 | + continue; |
| 200 | + |
| 201 | + // K0short |
| 202 | + if (v0.qtarm() / std::fabs(v0.alpha()) > cfgv0_ArmPodocut && std::fabs(v0.y()) < 0.5 && std::fabs(v0.mK0Short() - o2::constants::physics::MassK0Short) < cfgv0_mk0swindow && |
| 203 | + (!cfgcheckDauTPC || (std::fabs(v0posdau.tpcNSigmaPi()) < cfgNSigma[0] && std::fabs(v0negdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 204 | + registry.fill(HIST("h2DRecK0s"), v0.pt(), rectracknum); |
| 205 | + } |
| 206 | + // Lambda and antiLambda |
| 207 | + if (std::fabs(v0.y()) < 0.5 && std::fabs(v0.mLambda() - o2::constants::physics::MassLambda) < cfgv0_mlambdawindow && |
| 208 | + (!cfgcheckDauTPC || (std::fabs(v0posdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(v0negdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 209 | + registry.fill(HIST("h2DRecLambda"), v0.pt(), rectracknum); |
| 210 | + } else if (std::fabs(v0.y()) < 0.5 && std::fabs(v0.mLambda() - o2::constants::physics::MassLambda) < cfgv0_mlambdawindow && |
| 211 | + (!cfgcheckDauTPC || (std::fabs(v0negdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(v0posdau.tpcNSigmaPi()) < cfgNSigma[0]))) { |
| 212 | + registry.fill(HIST("h2DRecLambda"), v0.pt(), rectracknum); |
| 213 | + } |
| 214 | + } |
| 215 | + } |
| 216 | + PROCESS_SWITCH(FlowEfficiencyCasc, processRec, "process reconstructed information", true); |
| 217 | + |
| 218 | + void processGen(MyMcCollisions::iterator const&, soa::SmallGroups<soa::Join<aod::StraCollisions, aod::StraEvSels, aod::StraCollLabels>> const& coll, const soa::SmallGroups<soa::Join<aod::CascMCCores, aod::CascMCCollRefs>>& cascMCs, const soa::SmallGroups<soa::Join<aod::V0MCCores, aod::V0MCCollRefs>>& v0MCs) |
| 219 | + { |
| 220 | + registry.fill(HIST("mcEventCounter"), 0.5); |
| 221 | + int rectracknum = 0; |
| 222 | + for (const auto& col : coll) { |
| 223 | + rectracknum = col.multNTracksGlobal(); |
| 224 | + } |
| 225 | + for (auto const& cascmc : cascMCs) { |
| 226 | + if (std::abs(cascmc.pdgCode()) == kXiMinus) { |
| 227 | + if (std::fabs(cascmc.yMC()) < cfgCasc_rapidity) |
| 228 | + registry.fill(HIST("h2DGenXi"), cascmc.ptMC(), rectracknum); |
| 229 | + } |
| 230 | + if (std::abs(cascmc.pdgCode()) == kOmegaMinus) { |
| 231 | + if (std::fabs(cascmc.yMC()) < cfgCasc_rapidity) |
| 232 | + registry.fill(HIST("h2DGenOmega"), cascmc.ptMC(), rectracknum); |
| 233 | + } |
| 234 | + } |
| 235 | + for (auto const& v0mc : v0MCs) { |
| 236 | + if (std::abs(v0mc.pdgCode()) == kK0Short) { |
| 237 | + if (std::fabs(v0mc.yMC()) < cfgCasc_rapidity) |
| 238 | + registry.fill(HIST("h2DGenK0s"), v0mc.ptMC(), rectracknum); |
| 239 | + } |
| 240 | + if (std::abs(v0mc.pdgCode()) == kLambda0) { |
| 241 | + if (std::fabs(v0mc.yMC()) < cfgCasc_rapidity) |
| 242 | + registry.fill(HIST("h2DGenLambda"), v0mc.ptMC(), rectracknum); |
| 243 | + } |
| 244 | + } |
| 245 | + } |
| 246 | + PROCESS_SWITCH(FlowEfficiencyCasc, processGen, "process gen information", true); |
| 247 | +}; |
| 248 | + |
| 249 | +WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) |
| 250 | +{ |
| 251 | + return WorkflowSpec{ |
| 252 | + adaptAnalysisTask<FlowEfficiencyCasc>(cfgc)}; |
| 253 | +} |
0 commit comments