Skip to content

Commit cffc55c

Browse files
authored
[PWGCF] calculate and apply local density efficiency
Calculate and apply local density efficiency correction of cascades and v0s
1 parent 22ae462 commit cffc55c

File tree

2 files changed

+278
-0
lines changed

2 files changed

+278
-0
lines changed

PWGCF/Flow/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,3 +68,8 @@ o2physics_add_dpl_workflow(resonances-gfw-flow
6868
SOURCES resonancesGfwFlow.cxx
6969
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore
7070
COMPONENT_NAME Analysis)
71+
72+
o2physics_add_dpl_workflow(flow-efficiency-casc
73+
SOURCES flowEfficiencyCasc.cxx
74+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore
75+
COMPONENT_NAME Analysis)
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
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([email protected])
14+
/// \since Feb/21/2025
15+
/// \brief This task is to calculate V0s and cascades local density efficiency
16+
17+
#include <iostream>
18+
#include <vector>
19+
#include "Common/DataModel/Centrality.h"
20+
#include "Common/DataModel/Multiplicity.h"
21+
#include "Common/DataModel/TrackSelectionTables.h"
22+
#include "Common/DataModel/EventSelection.h"
23+
#include "Framework/runDataProcessing.h"
24+
#include "Framework/AnalysisTask.h"
25+
#include "Framework/ASoAHelpers.h"
26+
#include "Common/Core/TrackSelection.h"
27+
#include "Common/Core/TrackSelectionDefaults.h"
28+
#include "Common/DataModel/PIDResponse.h"
29+
#include "PWGLF/DataModel/cascqaanalysis.h"
30+
#include "PWGLF/DataModel/LFStrangenessTables.h"
31+
#include "PWGLF/DataModel/LFStrangenessPIDTables.h"
32+
#include "CommonConstants/PhysicsConstants.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, 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.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.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.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+
const AxisSpec axisCounter{1, 0, +1, ""};
93+
// create histograms
94+
registry.add("eventCounter", "eventCounter", kTH1F, {axisCounter});
95+
registry.add("mcEventCounter", "Monte Carlo Truth EventCounter", kTH1F, {axisCounter});
96+
97+
registry.add("h2DGenK0s", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}});
98+
registry.add("h2DGenLambda", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}});
99+
registry.add("h2DGenXi", "", {HistType::kTH2D, {cfgaxisPtXi, cfgaxisMultiplicity}});
100+
registry.add("h2DGenOmega", "", {HistType::kTH2D, {cfgaxisPtOmega, cfgaxisMultiplicity}});
101+
registry.add("h2DRecK0s", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}});
102+
registry.add("h2DRecLambda", "", {HistType::kTH2D, {cfgaxisPtV0, cfgaxisMultiplicity}});
103+
registry.add("h2DRecXi", "", {HistType::kTH2D, {cfgaxisPtXi, cfgaxisMultiplicity}});
104+
registry.add("h2DRecOmega", "", {HistType::kTH2D, {cfgaxisPtOmega, cfgaxisMultiplicity}});
105+
}
106+
107+
bool isStable(int pdg)
108+
{
109+
if (abs(pdg) == 211)
110+
return true;
111+
if (abs(pdg) == 321)
112+
return true;
113+
if (abs(pdg) == 2212)
114+
return true;
115+
if (abs(pdg) == 11)
116+
return true;
117+
if (abs(pdg) == 13)
118+
return true;
119+
return false;
120+
}
121+
122+
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&)
123+
{
124+
registry.fill(HIST("eventCounter"), 0.5);
125+
if (!collision.sel8())
126+
return;
127+
int rectracknum = collision.multNTracksGlobal();
128+
for (auto& casc : Cascades) {
129+
if (!casc.has_cascMCCore())
130+
continue;
131+
auto cascMC = casc.cascMCCore_as<soa::Join<aod::CascMCCores, aod::CascMCCollRefs>>();
132+
auto negdau = casc.negTrackExtra_as<DaughterTracks>();
133+
auto posdau = casc.posTrackExtra_as<DaughterTracks>();
134+
auto bachelor = casc.bachTrackExtra_as<DaughterTracks>();
135+
// track quality check
136+
if (bachelor.tpcNClsFound() < cfgtpcclusters)
137+
continue;
138+
if (posdau.tpcNClsFound() < cfgtpcclusters)
139+
continue;
140+
if (negdau.tpcNClsFound() < cfgtpcclusters)
141+
continue;
142+
if (bachelor.itsNCls() < cfgitsclusters)
143+
continue;
144+
if (posdau.itsNCls() < cfgitsclusters)
145+
continue;
146+
if (negdau.itsNCls() < cfgitsclusters)
147+
continue;
148+
// topological cut
149+
if (casc.cascradius() < cfgcasc_radius)
150+
continue;
151+
if (casc.casccosPA(collision.posX(), collision.posY(), collision.posZ()) < cfgcasc_casccospa)
152+
continue;
153+
if (casc.v0cosPA(collision.posX(), collision.posY(), collision.posZ()) < cfgcasc_v0cospa)
154+
continue;
155+
if (std::fabs(casc.dcav0topv(collision.posX(), collision.posY(), collision.posZ())) < cfgcasc_dcav0topv)
156+
continue;
157+
if (std::fabs(casc.dcabachtopv()) < cfgcasc_dcabachtopv)
158+
continue;
159+
if (casc.dcacascdaughters() > cfgcasc_dcacascdau)
160+
continue;
161+
if (casc.dcaV0daughters() > cfgcasc_dcav0dau)
162+
continue;
163+
if (std::fabs(casc.mLambda() - o2::constants::physics::MassLambda0) > cfgcasc_mlambdawindow)
164+
continue;
165+
// Omega and antiOmega
166+
if (casc.sign() < 0 && (casc.mOmega() > 1.63) && (casc.mOmega() < 1.71) && std::fabs(casc.yOmega()) < cfgCasc_rapidity &&
167+
(!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaKa()) < cfgNSigma[2] && std::fabs(posdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(negdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
168+
registry.fill(HIST("h2DRecOmega"), casc.pt(), rectracknum);;
169+
} else if (casc.sign() < 0 && (casc.mOmega() > 1.63) && (casc.mOmega() < 1.71) && std::fabs(casc.yOmega()) < cfgCasc_rapidity &&
170+
(!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaKa()) < cfgNSigma[2] && std::fabs(negdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(posdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
171+
registry.fill(HIST("h2DRecOmega"), casc.pt(), rectracknum);
172+
}
173+
// Xi and antiXi
174+
if (casc.sign() < 0 && (casc.mXi() > 1.30) && (casc.mXi() < 1.37) && std::fabs(casc.yXi()) < cfgCasc_rapidity &&
175+
(!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaPi()) < cfgNSigma[0] && std::fabs(posdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(negdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
176+
registry.fill(HIST("h2DRecXi"), casc.pt(), rectracknum);
177+
} else if (casc.sign() < 0 && (casc.mXi() > 1.30) && (casc.mXi() < 1.37) && std::fabs(casc.yXi()) < cfgCasc_rapidity &&
178+
(!cfgcheckDauTPC || (std::fabs(bachelor.tpcNSigmaPi()) < cfgNSigma[0] && std::fabs(negdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(posdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
179+
registry.fill(HIST("h2DRecXi"), casc.pt(), rectracknum);
180+
}
181+
182+
}
183+
184+
for (auto& v0 : V0s) {
185+
if (!v0.has_v0MCCore())
186+
continue;
187+
auto v0MC = v0.v0MCCore_as<soa::Join<aod::V0MCCores, aod::V0MCCollRefs>>();
188+
auto v0negdau = v0.negTrackExtra_as<DaughterTracks>();
189+
auto v0posdau = v0.posTrackExtra_as<DaughterTracks>();
190+
191+
// track quality check
192+
if (v0posdau.tpcNClsFound() < cfgtpcclusters)
193+
continue;
194+
if (v0negdau.tpcNClsFound() < cfgtpcclusters)
195+
continue;
196+
if (v0posdau.tpcNClsFindable() < cfgtpcclufindable)
197+
continue;
198+
if (v0negdau.tpcNClsFindable() < cfgtpcclufindable)
199+
continue;
200+
if (v0posdau.tpcCrossedRowsOverFindableCls() < cfgtpccrossoverfindable)
201+
continue;
202+
if (v0posdau.itsNCls() < cfgitsclusters)
203+
continue;
204+
if (v0negdau.itsNCls() < cfgitsclusters)
205+
continue;
206+
// topological cut
207+
if (v0.v0radius() < cfgv0_radius)
208+
continue;
209+
if (v0.v0cosPA() < cfgv0_v0cospa)
210+
continue;
211+
if (v0.dcaV0daughters() > cfgv0_dcav0dau)
212+
continue;
213+
if (std::fabs(v0.dcapostopv()) < cfgv0_dcadautopv)
214+
continue;
215+
if (std::fabs(v0.dcanegtopv()) < cfgv0_dcadautopv)
216+
continue;
217+
218+
// K0short
219+
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 &&
220+
(!cfgcheckDauTPC || (std::fabs(v0posdau.tpcNSigmaPi()) < cfgNSigma[0] && std::fabs(v0negdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
221+
registry.fill(HIST("h2DRecK0s"), v0.pt(), rectracknum);
222+
}
223+
// Lambda and antiLambda
224+
if (std::fabs(v0.y()) < 0.5 && std::fabs(v0.mLambda() - o2::constants::physics::MassLambda) < cfgv0_mlambdawindow &&
225+
(!cfgcheckDauTPC || (std::fabs(v0posdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(v0negdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
226+
registry.fill(HIST("h2DRecLambda"), v0.pt(), rectracknum);
227+
} else if (std::fabs(v0.y()) < 0.5 && std::fabs(v0.mLambda() - o2::constants::physics::MassLambda) < cfgv0_mlambdawindow &&
228+
(!cfgcheckDauTPC || (std::fabs(v0negdau.tpcNSigmaPr()) < cfgNSigma[1] && std::fabs(v0posdau.tpcNSigmaPi()) < cfgNSigma[0]))) {
229+
registry.fill(HIST("h2DRecLambda"), v0.pt(), rectracknum);
230+
}
231+
}
232+
233+
234+
235+
}
236+
PROCESS_SWITCH(flowEfficiencyCasc, processRec, "process reconstructed information", true);
237+
238+
void processGen(myMcCollisions::iterator const& collision, soa::Join<aod::StraCollisions, aod::StraEvSels> const& coll, const soa::SmallGroups<soa::Join<aod::CascMCCores, aod::CascMCCollRefs>>& cascMCs, const soa::SmallGroups<soa::Join<aod::V0MCCores, aod::V0MCCollRefs>>& v0MCs)
239+
{
240+
registry.fill(HIST("mcEventCounter"), 0.5);
241+
int rectracknum = 0;
242+
for (const auto& col : coll) {
243+
rectracknum = col.multNTracksGlobal();
244+
}
245+
for (auto const& cascmc : cascMCs) {
246+
if (TMath::Abs(cascmc.pdgCode()) == 3312) {
247+
if (std::fabs(cascmc.yMC()) < cfgCasc_rapidity)
248+
registry.fill(HIST("h2DGenXi"), cascmc.ptMC(), rectracknum);
249+
}
250+
if (TMath::Abs(cascmc.pdgCode() == 3334)) {
251+
if (std::fabs(cascmc.yMC()) < cfgCasc_rapidity)
252+
registry.fill(HIST("h2DGenOmega"), cascmc.ptMC(), rectracknum);
253+
}
254+
}
255+
for (auto const& v0mc : v0MCs) {
256+
if (TMath::Abs(v0mc.pdgCode()) == 310) {
257+
if (std::fabs(v0mc.yMC()) < cfgCasc_rapidity)
258+
registry.fill(HIST("h2DGenK0s"), v0mc.ptMC(), rectracknum);
259+
}
260+
if (TMath::Abs(v0mc.pdgCode() == 3122)) {
261+
if (std::fabs(v0mc.yMC()) < cfgCasc_rapidity)
262+
registry.fill(HIST("h2DGenLambda"), v0mc.ptMC(), rectracknum);
263+
}
264+
}
265+
}
266+
PROCESS_SWITCH(flowEfficiencyCasc, processGen, "process gen information", true);
267+
};
268+
269+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
270+
{
271+
return WorkflowSpec{
272+
adaptAnalysisTask<flowEfficiencyCasc>(cfgc)};
273+
}

0 commit comments

Comments
 (0)