Skip to content

Commit d8691b5

Browse files
maciaccoalibuild
andauthored
add task to study antideuteron-lambda fluctuations (AliceO2Group#4356)
* add task to study antideuteron-lambda fluctuations * Please consider the following formatting changes * add empty newline --------- Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent dc330f6 commit d8691b5

2 files changed

Lines changed: 338 additions & 0 deletions

File tree

PWGLF/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@ o2physics_add_dpl_workflow(hyhefour-analysis
6363
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
6464
COMPONENT_NAME Analysis)
6565

66+
o2physics_add_dpl_workflow(antid-lambda-ebye
67+
SOURCES antidLambdaEbye.cxx
68+
PUBLIC_LINK_LIBRARIES O2Physics::AnalysisCore
69+
COMPONENT_NAME Analysis)
70+
6671
# Spectra
6772
o2physics_add_dpl_workflow(mc-spectra-efficiency
6873
SOURCES mcspectraefficiency.cxx

PWGLF/Tasks/antidLambdaEbye.cxx

Lines changed: 333 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,333 @@
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+
#include <vector>
13+
14+
#include "Framework/runDataProcessing.h"
15+
#include "Framework/AnalysisTask.h"
16+
#include "Framework/AnalysisDataModel.h"
17+
#include "Framework/ASoAHelpers.h"
18+
#include "ReconstructionDataFormats/Track.h"
19+
#include "Common/Core/RecoDecay.h"
20+
#include "Common/Core/trackUtilities.h"
21+
#include "Common/DataModel/EventSelection.h"
22+
#include "PWGLF/DataModel/LFStrangenessTables.h"
23+
#include "DetectorsBase/Propagator.h"
24+
#include "DetectorsBase/GeometryManager.h"
25+
#include "DataFormatsParameters/GRPObject.h"
26+
#include "DataFormatsParameters/GRPMagField.h"
27+
#include "CCDB/BasicCCDBManager.h"
28+
29+
#include "Common/Core/PID/TPCPIDResponse.h"
30+
#include "Common/DataModel/PIDResponse.h"
31+
32+
#include "TDatabasePDG.h"
33+
34+
using namespace o2;
35+
using namespace o2::framework;
36+
using namespace o2::framework::expressions;
37+
38+
using TracksFull = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksCovIU, aod::pidTPCDe, aod::pidTPCPr, aod::pidTPCPi, aod::pidTOFDe>;
39+
40+
namespace
41+
{
42+
const float lambdaMassPDG = TDatabasePDG::Instance()->GetParticle(3122)->Mass();
43+
}
44+
45+
struct antidLambdaEbye {
46+
Service<o2::ccdb::BasicCCDBManager> ccdb;
47+
48+
Configurable<int> cfgMaterialCorrection{"cfgMaterialCorrection", static_cast<int>(o2::base::Propagator::MatCorrType::USEMatCorrNONE), "Type of material correction"};
49+
50+
ConfigurableAxis zVtxAxis{"zVtxBins", {100, -20.f, 20.f}, "Binning for the vertex z in cm"};
51+
ConfigurableAxis massLambdaAxis{"massLambdaAxis", {400, lambdaMassPDG - 0.03f, lambdaMassPDG + 0.03f}, "binning for the lambda invariant-mass"};
52+
ConfigurableAxis centAxis{"centAxis", {106, 0, 106}, "binning for the centrality"};
53+
54+
ConfigurableAxis cosPaAxis{"cosPaAxis", {1e3, 0.95f, 1.00f}, "binning for the cosPa axis"};
55+
ConfigurableAxis radiusAxis{"radiusAxis", {1e3, 0.f, 100.f}, "binning for the radius axis"};
56+
ConfigurableAxis dcaV0daughAxis{"dcaV0daughAxis", {2e2, 0.f, 2.f}, "binning for the dca of V0 daughters"};
57+
ConfigurableAxis dcaDaughPvAxis{"dcaDaughPvAxis", {1e3, 0.f, 10.f}, "binning for the dca of positive daughter to PV"};
58+
59+
ConfigurableAxis tpcNsigmaAxis{"tpcNsigmaAxis", {100, -5.f, 5.f}, "tpc nsigma axis"};
60+
ConfigurableAxis tofNsigmaAxis{"tofNsigmaAxis", {100, -5.f, 5.f}, "tof nsigma axis"};
61+
62+
// CCDB options
63+
Configurable<double> d_bz_input{"d_bz", -999, "bz field, -999 is automatic"};
64+
Configurable<std::string> ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
65+
Configurable<std::string> grpPath{"grpPath", "GLO/GRP/GRP", "Path of the grp file"};
66+
Configurable<std::string> grpmagPath{"grpmagPath", "GLO/Config/GRPMagField", "CCDB path of the GRPMagField object"};
67+
Configurable<std::string> lutPath{"lutPath", "GLO/Param/MatLUT", "Path of the Lut parametrization"};
68+
Configurable<std::string> geoPath{"geoPath", "GLO/Config/GeometryAligned", "Path of the geometry file"};
69+
Configurable<std::string> pidPath{"pidPath", "", "Path to the PID response object"};
70+
71+
Configurable<float> zVtxMax{"zVtxMax", 10.0f, "maximum z position of the primary vertex"};
72+
Configurable<float> etaMax{"etaMax", 0.8f, "maximum eta"};
73+
74+
Configurable<float> antidPtMin{"antidPtMin", 0.8f, "minimum antideuteron pT (GeV/c)"};
75+
Configurable<float> antidPtTof{"antidPtTof", 1.0f, "antideuteron pT to switch to TOF pid (GeV/c) "};
76+
Configurable<float> antidPtMax{"antidPtMax", 1.8f, "maximum antideuteron pT (GeV/c)"};
77+
78+
Configurable<float> lambdaPtMin{"lambdaPtMin", 0.5f, "minimum (anti)lambda pT (GeV/c)"};
79+
Configurable<float> lambdaPtMax{"lambdaPtMax", 3.0f, "maximum (anti)lambda pT (GeV/c)"};
80+
81+
Configurable<float> antidNclusItsCut{"antidNclusITScut", 5, "Minimum number of ITS clusters"};
82+
Configurable<float> antidNclusTpcCut{"antidNclusTPCcut", 70, "Minimum number of TPC clusters"};
83+
Configurable<float> antidNsigmaTpcCut{"antidNsigmaTpcCut", 4.f, "TPC PID cut"};
84+
Configurable<float> antidNsigmaTofCut{"antidNsigmaTofCut", 4.f, "TOF PID cut"};
85+
Configurable<float> antidDcaCut{"antidDcaCut", 0.1f, "DCA antid to PV"};
86+
87+
Configurable<float> v0setting_dcav0dau{"v0setting_dcav0dau", 1, "DCA V0 Daughters"};
88+
Configurable<float> v0setting_dcapostopv{"v0setting_dcapostopv", 0.1f, "DCA Pos To PV"};
89+
Configurable<float> v0setting_dcanegtopv{"v0setting_dcanegtopv", 0.1f, "DCA Neg To PV"};
90+
Configurable<double> v0setting_cospa{"v0setting_cospa", 0.98, "V0 CosPA"};
91+
Configurable<float> v0setting_radius{"v0setting_radius", 0.5f, "v0radius"};
92+
Configurable<float> lambdaMassCut{"lambdaMassCut", 0.005f, "maximum deviation from PDG mass"};
93+
94+
int mRunNumber;
95+
float d_bz;
96+
97+
HistogramRegistry histos{"histos", {}, OutputObjHandlingPolicy::AnalysisObject};
98+
99+
Filter preFilterV0 = (nabs(aod::v0data::dcapostopv) > v0setting_dcapostopv &&
100+
nabs(aod::v0data::dcanegtopv) > v0setting_dcanegtopv &&
101+
aod::v0data::dcaV0daughters < v0setting_dcav0dau);
102+
103+
template <class RecV0>
104+
bool selectLambda(RecV0 const& v0) // TODO: apply ML
105+
{
106+
if (std::abs(v0.eta()) > etaMax ||
107+
v0.v0cosPA() < v0setting_cospa ||
108+
v0.v0radius() < v0setting_radius) {
109+
return false;
110+
}
111+
auto mLambda = v0.alpha() > 0 ? v0.mLambda() : v0.mAntiLambda();
112+
if (std::abs(mLambda - lambdaMassPDG) > lambdaMassCut) {
113+
return false;
114+
}
115+
return true;
116+
}
117+
118+
template <class T>
119+
bool selectAntid(T const& track)
120+
{
121+
if (std::abs(track.eta()) > etaMax) {
122+
return false;
123+
}
124+
if (track.sign() > 0.) {
125+
return false;
126+
}
127+
if (track.itsNCls() < antidNclusItsCut ||
128+
track.tpcNClsFound() < antidNclusTpcCut ||
129+
track.tpcNClsCrossedRows() < 70 ||
130+
track.tpcNClsCrossedRows() < 0.8 * track.tpcNClsFindable() ||
131+
track.tpcChi2NCl() > 4.f ||
132+
track.itsChi2NCl() > 36.f ||
133+
!(track.trackType() & o2::aod::track::TPCrefit) ||
134+
!(track.trackType() & o2::aod::track::ITSrefit)) {
135+
return false;
136+
}
137+
return true;
138+
}
139+
140+
void init(o2::framework::InitContext&)
141+
{
142+
ccdb->setURL(ccdburl);
143+
ccdb->setCaching(true);
144+
ccdb->setLocalObjectValidityChecking();
145+
ccdb->setFatalWhenNull(false);
146+
147+
mRunNumber = 0;
148+
d_bz = 0;
149+
150+
histos.add<TH1>("zVtx", ";#it{z}_{vtx} (cm);Entries", HistType::kTH1F, {zVtxAxis});
151+
152+
histos.add<TH1>("nEv", ";#it{N}_{ev};Entries", {HistType::kTH1D}, {centAxis});
153+
154+
histos.add<TH1>("q1antid", ";Centrality (%);#it{q}_{1}(#bar{d})", {HistType::kTH1D}, {centAxis});
155+
histos.add<TH1>("q1sqantid", ";Centrality (%);#it{q}_{1}^{2}(#bar{d})", {HistType::kTH1D}, {centAxis});
156+
histos.add<TH1>("q2antid", ";Centrality (%);#it{q}_{2}(#bar{d})", {HistType::kTH1D}, {centAxis});
157+
158+
histos.add<TH1>("q1antiL", ";Centrality (%);#it{q}_{1}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis});
159+
histos.add<TH1>("q1sqantiL", ";Centrality (%);#it{q}_{1}^{2}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis});
160+
histos.add<TH1>("q2antiL", ";Centrality (%);#it{q}_{2}(#bar{#Lambda})", {HistType::kTH1D}, {centAxis});
161+
162+
histos.add<TH1>("q1L", ";Centrality (%);#it{q}_{1}(#Lambda)", {HistType::kTH1D}, {centAxis});
163+
histos.add<TH1>("q1sqL", ";Centrality (%);#it{q}_{1}^{2}(#Lambda)", {HistType::kTH1D}, {centAxis});
164+
histos.add<TH1>("q2L", ";Centrality (%);#it{q}_{2}(#Lambda)", {HistType::kTH1D}, {centAxis});
165+
166+
histos.add<TH1>("q11Lantid", ";Centrality (%);#it{q}_{11}(#Lambda, #bar{d})", {HistType::kTH1D}, {centAxis});
167+
histos.add<TH1>("q11antiLantid", ";Centrality (%);#it{q}_{11}(#bar{#Lambda}, #bar{d})", {HistType::kTH1D}, {centAxis});
168+
169+
// v0 QA
170+
histos.add<TH1>("massLambda", ";#it{M}(p + #pi^{-}) (GeV/#it{c}^{2});Entries", {HistType::kTH1F, {massLambdaAxis}});
171+
histos.add<TH1>("cosPa", ";cosPa;Entries", {HistType::kTH1F}, {cosPaAxis});
172+
histos.add<TH1>("radius", ";radius;Entries", {HistType::kTH1F}, {radiusAxis});
173+
histos.add<TH1>("dcaV0daugh", ";dcaV0daugh;Entries", {HistType::kTH1F}, {dcaV0daughAxis});
174+
histos.add<TH1>("dcaPosPv", ";dcaPosPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis});
175+
histos.add<TH1>("dcaNegPv", ";dcaNegPv;Entries", {HistType::kTH1F}, {dcaDaughPvAxis});
176+
177+
// v0 QA
178+
histos.add<TH1>("tpcNsigma", ";tpcNsigma;Entries", {HistType::kTH1F, {tpcNsigmaAxis}});
179+
histos.add<TH1>("tofNsigma", ";tofNsigma;Entries", {HistType::kTH1F}, {tofNsigmaAxis});
180+
}
181+
182+
void initCCDB(aod::BCsWithTimestamps::iterator const& bc)
183+
{
184+
if (mRunNumber == bc.runNumber()) {
185+
return;
186+
}
187+
auto run3grp_timestamp = bc.timestamp();
188+
189+
o2::parameters::GRPObject* grpo = ccdb->getForTimeStamp<o2::parameters::GRPObject>(grpPath, run3grp_timestamp);
190+
o2::parameters::GRPMagField* grpmag = 0x0;
191+
if (grpo) {
192+
o2::base::Propagator::initFieldFromGRP(grpo);
193+
if (d_bz_input < -990) {
194+
// Fetch magnetic field from ccdb for current collision
195+
d_bz = grpo->getNominalL3Field();
196+
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG";
197+
} else {
198+
d_bz = d_bz_input;
199+
}
200+
} else {
201+
grpmag = ccdb->getForTimeStamp<o2::parameters::GRPMagField>(grpmagPath, run3grp_timestamp);
202+
if (!grpmag) {
203+
LOG(fatal) << "Got nullptr from CCDB for path " << grpmagPath << " of object GRPMagField and " << grpPath << " of object GRPObject for timestamp " << run3grp_timestamp;
204+
}
205+
o2::base::Propagator::initFieldFromGRP(grpmag);
206+
if (d_bz_input < -990) {
207+
// Fetch magnetic field from ccdb for current collision
208+
d_bz = std::lround(5.f * grpmag->getL3Current() / 30000.f);
209+
LOG(info) << "Retrieved GRP for timestamp " << run3grp_timestamp << " with magnetic field of " << d_bz << " kZG";
210+
} else {
211+
d_bz = d_bz_input;
212+
}
213+
}
214+
mRunNumber = bc.runNumber();
215+
}
216+
217+
void process(soa::Join<aod::Collisions, aod::EvSels, aod::CentFT0Cs>::iterator const& collision, TracksFull const& tracks, soa::Filtered<aod::V0Datas> const& V0s, aod::BCsWithTimestamps const&)
218+
{
219+
auto bc = collision.bc_as<aod::BCsWithTimestamps>();
220+
initCCDB(bc);
221+
222+
if (!collision.sel8())
223+
return;
224+
225+
if (std::abs(collision.posZ()) > zVtxMax)
226+
return;
227+
228+
const o2::math_utils::Point3D<float> collVtx{collision.posX(), collision.posY(), collision.posZ()};
229+
230+
histos.fill(HIST("zVtx"), collision.posZ());
231+
232+
double q1antid{0.}, q2antid{0.};
233+
for (const auto& track : tracks) {
234+
if (!selectAntid(track)) {
235+
continue;
236+
}
237+
238+
auto trackParCov = getTrackParCov(track);
239+
gpu::gpustd::array<float, 2> dcaInfo;
240+
o2::base::Propagator::Instance()->propagateToDCABxByBz(collVtx, trackParCov, 2.f, static_cast<o2::base::Propagator::MatCorrType>(cfgMaterialCorrection.value), &dcaInfo);
241+
242+
float dcaXYZ = dcaInfo[0];
243+
if (std::abs(dcaXYZ) > antidDcaCut) {
244+
continue;
245+
}
246+
247+
if (trackParCov.getPt() < antidPtMin || trackParCov.getPt() > antidPtMax) {
248+
continue;
249+
}
250+
if (std::abs(track.tpcNSigmaDe()) > antidNsigmaTpcCut) {
251+
continue;
252+
}
253+
if (std::abs(track.tofNSigmaDe()) > antidNsigmaTofCut && trackParCov.getPt() > antidPtTof) {
254+
continue;
255+
}
256+
257+
histos.fill(HIST("tpcNsigma"), track.tpcNSigmaDe());
258+
if (trackParCov.getPt() > antidPtTof) {
259+
histos.fill(HIST("tofNsigma"), track.tofNSigmaDe());
260+
}
261+
262+
q1antid += 1.; // TODO: correct for efficiency
263+
q2antid += 1.;
264+
}
265+
266+
double q1L{0.}, q2L{0.}, q1antiL{0.}, q2antiL{0.};
267+
std::vector<int64_t> trkId;
268+
for (const auto& v0 : V0s) {
269+
if (v0.pt() < lambdaPtMin || v0.pt() > lambdaPtMax) {
270+
continue;
271+
}
272+
273+
if (!selectLambda(v0)) {
274+
continue;
275+
}
276+
277+
auto pos = v0.template posTrack_as<TracksFull>();
278+
auto neg = v0.template negTrack_as<TracksFull>();
279+
if (std::abs(pos.eta()) > etaMax || std::abs(pos.eta()) > etaMax) {
280+
continue;
281+
}
282+
283+
bool matter = v0.alpha() > 0;
284+
285+
histos.fill(HIST("massLambda"), matter ? v0.mLambda() : v0.mAntiLambda());
286+
histos.fill(HIST("cosPa"), v0.v0cosPA());
287+
histos.fill(HIST("radius"), v0.v0radius());
288+
histos.fill(HIST("dcaV0daugh"), v0.dcaV0daughters());
289+
histos.fill(HIST("dcaPosPv"), v0.dcapostopv());
290+
histos.fill(HIST("dcaNegPv"), v0.dcanegtopv());
291+
292+
if (matter) {
293+
q1L += 1.; // TODO: correct for efficiency
294+
q2L += 1.;
295+
} else {
296+
q1antiL += 1.; // TODO: correct for efficiency
297+
q2antiL += 1.;
298+
}
299+
300+
trkId.emplace_back(pos.globalIndex());
301+
trkId.emplace_back(neg.globalIndex());
302+
}
303+
304+
// reject events having multiple v0s from same tracks (TODO: also across collisions?)
305+
std::sort(trkId.begin(), trkId.end());
306+
if (std::adjacent_find(trkId.begin(), trkId.end()) != trkId.end()) {
307+
return;
308+
}
309+
310+
histos.fill(HIST("nEv"), collision.centFT0C());
311+
312+
histos.fill(HIST("q1antid"), collision.centFT0C(), q1antid);
313+
histos.fill(HIST("q1sqantid"), collision.centFT0C(), std::pow(q1antid, 2));
314+
histos.fill(HIST("q2antid"), collision.centFT0C(), q2antid);
315+
316+
histos.fill(HIST("q1L"), collision.centFT0C(), q1L);
317+
histos.fill(HIST("q1sqL"), collision.centFT0C(), std::pow(q1L, 2));
318+
histos.fill(HIST("q2L"), collision.centFT0C(), q2L);
319+
320+
histos.fill(HIST("q1antiL"), collision.centFT0C(), q1antiL);
321+
histos.fill(HIST("q1sqantiL"), collision.centFT0C(), std::pow(q1antiL, 2));
322+
histos.fill(HIST("q2antiL"), collision.centFT0C(), q2antiL);
323+
324+
histos.fill(HIST("q11Lantid"), collision.centFT0C(), q1L * q1antid);
325+
histos.fill(HIST("q11antiLantid"), collision.centFT0C(), q1antiL * q1antid);
326+
}
327+
};
328+
329+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
330+
{
331+
return WorkflowSpec{
332+
adaptAnalysisTask<antidLambdaEbye>(cfgc)};
333+
}

0 commit comments

Comments
 (0)