Skip to content

Commit 545d843

Browse files
Nicola RubiniNicola Rubininjacazioalibuild
authored
LF: First test rsn analysis (#962)
* Add first analysis for RSN Co-authored-by: Nicola Rubini <nrubini@Nicolas-MacBook-Pro.local> Co-authored-by: Nicolò Jacazio <njacazio@users.noreply.github.com> Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 3ba5615 commit 545d843

File tree

2 files changed

+368
-1
lines changed

2 files changed

+368
-1
lines changed

PWGLF/Tasks/CMakeLists.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,7 @@ o2physics_add_dpl_workflow(track-checks
9494
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase
9595
COMPONENT_NAME Analysis)
9696

97-
97+
o2physics_add_dpl_workflow(rsnanalysis
98+
SOURCES rsnanalysis.cxx
99+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2::DetectorsBase
100+
COMPONENT_NAME Analysis)

PWGLF/Tasks/rsnanalysis.cxx

Lines changed: 364 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,364 @@
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 rsn_analysis.cxx
13+
/// \brief Analysis task for the measurement of resonances
14+
/// \author Nicola Rubini <nrubini@cern.ch>
15+
16+
// O2 includes
17+
#include "Common/DataModel/EventSelection.h"
18+
#include "Common/DataModel/PIDResponse.h"
19+
#include "Common/DataModel/TrackSelectionTables.h"
20+
#include "Framework/AnalysisTask.h"
21+
#include "Framework/runDataProcessing.h"
22+
#include "TLorentzVector.h"
23+
24+
using namespace std;
25+
using namespace o2;
26+
using namespace o2::framework;
27+
28+
enum EventSelection { kNoSelection = 0,
29+
kTVXselection = 1,
30+
kVertexCut = 2 };
31+
32+
using kCollisionsTable = soa::Join<aod::Collisions, aod::EvSels>;
33+
using kTracksTable =
34+
soa::Join<aod::Tracks, aod::TracksExtra, aod::TrackSelection,
35+
aod::TracksDCA, aod::pidTOFFullKa, aod::pidTPCFullKa,
36+
aod::pidTOFFullPi, aod::pidTPCFullPi>;
37+
38+
struct rsn_analysis {
39+
HistogramRegistry uHistograms{
40+
"Histograms",
41+
{},
42+
OutputObjHandlingPolicy::AnalysisObject};
43+
//
44+
// Create Output Objects
45+
void init(o2::framework::InitContext&)
46+
{
47+
// Histogram is added to the ouput registry
48+
//
49+
// Event QA
50+
uHistograms.add("QA/Event/EnumEvents",
51+
"Event selection; ; "
52+
" Selected Events",
53+
kTH1F, {{10, 0, 10}});
54+
uHistograms.add("QA/Event/VertexZ",
55+
"Event selection; "
56+
"Vertex Z (cm); Selected Events",
57+
kTH1F, {{4000, -20, 20}});
58+
uHistograms.add("QA/Event/Selected/VertexZ",
59+
"Event selection; "
60+
"Vertex Z (cm); Selected Events",
61+
kTH1F, {{4000, -20, 20}});
62+
//
63+
// Track QA
64+
uHistograms.add("QA/Track/Momentum",
65+
"Momentum distribution of selected Tracks; "
66+
"#it{p} (GeV/#it{c}); Selected Tracks",
67+
kTH1F, {{1000, 0, 20}});
68+
uHistograms.add("QA/Track/TMomentum",
69+
"Transverse momentum distribution of selected Tracks; "
70+
"#it{p}_{T} (GeV/#it{c}); Selected Tracks",
71+
kTH1F, {{1000, 0, 20}});
72+
//
73+
// PID QA
74+
// --- Kaon
75+
uHistograms.add("QA/Kaon/TOF_TPC_Map",
76+
"TOF + TPC Combined PID for Kaons; "
77+
"#sigma_{TOF}^{Kaon}; #sigma_{TPC}^{Kaon}",
78+
kTH2F, {{1000, -10, 10}, {1000, -10, 10}});
79+
uHistograms.add("QA/Kaon/TOF_Nsigma",
80+
"TOF NSigma for Kaons; "
81+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TOF}^{Kaon};",
82+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
83+
uHistograms.add("QA/Kaon/TPC_Nsigma",
84+
"TPC NSigma for Kaons; "
85+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TPC}^{Kaon};",
86+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
87+
uHistograms.add("QA/Kaon/Selected/TOF_TPC_Map",
88+
"TOF + TPC Combined PID for Kaons; "
89+
"#sigma_{TPC}^{Kaon}; #sigma_{TPC}^{Kaon}",
90+
kTH2F, {{1000, -10, 10}, {1000, -10, 10}});
91+
uHistograms.add("QA/Kaon/Selected/TOF_Nsigma",
92+
"TOF NSigma for Kaons; "
93+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TOF}^{Kaon};",
94+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
95+
uHistograms.add("QA/Kaon/Selected/TPC_Nsigma",
96+
"TPC NSigma for Kaons; "
97+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TPC}^{Kaon};",
98+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
99+
// --- Pion
100+
uHistograms.add("QA/Pion/TOF_TPC_Map",
101+
"TOF + TPC Combined PID for Pions; "
102+
"#sigma_{TOF}^{Pion}; #sigma_{TPC}^{Pion}",
103+
kTH2F, {{1000, -10, 10}, {1000, -10, 10}});
104+
uHistograms.add("QA/Pion/TOF_Nsigma",
105+
"TOF NSigma for Pions; "
106+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TOF}^{Pion};",
107+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
108+
uHistograms.add("QA/Pion/TPC_Nsigma",
109+
"TPC NSigma for Pions; "
110+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TPC}^{Pion};",
111+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
112+
uHistograms.add("QA/Pion/Selected/TOF_TPC_Map",
113+
"TOF + TPC Combined PID for Pions; "
114+
"#sigma_{TPC}^{Pion}; #sigma_{TPC}^{Pion}",
115+
kTH2F, {{1000, -10, 10}, {1000, -10, 10}});
116+
uHistograms.add("QA/Pion/Selected/TOF_Nsigma",
117+
"TOF NSigma for Pions; "
118+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TOF}^{Pion};",
119+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
120+
uHistograms.add("QA/Pion/Selected/TPC_Nsigma",
121+
"TPC NSigma for Pions; "
122+
"#it{p}_{T} (GeV/#it{c}); #sigma_{TPC}^{Pion};",
123+
kTH2F, {{1000, 0, 20}, {1000, -10, 10}});
124+
//
125+
// Analysis Plots
126+
// --- Phi
127+
uHistograms.add("Analysis/Phi/FullInvariantMass",
128+
"K^{+}K^{-} Invariant Mass; "
129+
"M_{K^{+}K^{-}}; Counts;",
130+
kTH1F, {{1000, 0.99, 1.10}});
131+
uHistograms.add("Analysis/Phi/PTInvariantMass",
132+
"#it{p}_{T} (GeV/#it{c}); K^{+}K^{-} Invariant Mass; "
133+
" M_{K^{+}K^{-}};",
134+
kTH2F, {{1000, 0., 20.}, {1000, 0.99, 1.10}});
135+
// --- K*
136+
uHistograms.add("Analysis/Kstar/FullInvariantMass",
137+
"K^{#pm}#pi^{#pm} Invariant Mass; "
138+
"M_{K^{#pm}#pi^{#pm}}; Counts;",
139+
kTH1F, {{1000, 0.84, 0.95}});
140+
uHistograms.add("Analysis/Kstar/PTInvariantMass",
141+
"#it{p}_{T} (GeV/#it{c}); K^{#pm}#pi^{#pm} Invariant Mass; "
142+
" M_{K^{#pm}#pi^{#pm}};",
143+
kTH2F, {{1000, 0., 20.}, {1000, 0.84, 0.95}});
144+
}
145+
//
146+
// Configurables
147+
// --- Event
148+
Configurable<double> kVertexZ{"kVertexCut", 10., "Vertex Z Cut"};
149+
// --- PID
150+
// --- --- Kaons
151+
Configurable<double> kKaonsTOFveto{"kKaonsTOFveto", 3.,
152+
"TOF Veto NSigma for Kaons"};
153+
Configurable<double> kKaonsTPCveto{"kKaonsTPCveto", 5.,
154+
"TPC NSigma for Kaons w/ TOF Veto"};
155+
Configurable<double> kKaonsTPCstda{"kKaonsTPCstda", 3.,
156+
"TPC NSigma for Kaons Standalone"};
157+
// --- --- Pions
158+
Configurable<double> kPionsTOFveto{"kPionsTOFveto", 3.,
159+
"TOF Veto NSigma for Pions"};
160+
Configurable<double> kPionsTPCveto{"kPionsTPCveto", 5.,
161+
"TPC NSigma for Pions w/ TOF Veto"};
162+
Configurable<double> kPionsTPCstda{"kPionsTPCstda", 3.,
163+
"TPC NSigma for Pions Standalone"};
164+
//
165+
// Processing A02D
166+
void process(kCollisionsTable::iterator const& kCollision,
167+
kTracksTable const& kTracks)
168+
{
169+
//
170+
// Collision QA
171+
uHistograms.fill(HIST("QA/Event/EnumEvents"), EventSelection::kNoSelection);
172+
//
173+
// --- Event selection: Trigger based on TVX
174+
if (!kCollision.sel8())
175+
return;
176+
uHistograms.fill(HIST("QA/Event/EnumEvents"),
177+
EventSelection::kTVXselection);
178+
//
179+
// --- Event selection: Vertex position
180+
uHistograms.fill(HIST("QA/Event/VertexZ"), kCollision.posZ());
181+
if (!(fabs(kCollision.posZ()) < kVertexZ))
182+
return;
183+
uHistograms.fill(HIST("QA/Event/EnumEvents"), EventSelection::kVertexCut);
184+
uHistograms.fill(HIST("QA/Event/Selected/VertexZ"), kCollision.posZ());
185+
//
186+
// Storage for Kaons
187+
// --- PX PY PZ HasPositiveCharge
188+
std::vector<std::tuple<Float_t, Float_t, Float_t>> kPosSelectedKaons;
189+
std::vector<std::tuple<Float_t, Float_t, Float_t>> kNegSelectedKaons;
190+
std::vector<std::tuple<Float_t, Float_t, Float_t>> kPosSelectedPions;
191+
std::vector<std::tuple<Float_t, Float_t, Float_t>> kNegSelectedPions;
192+
//
193+
// Loop on Tracks
194+
for (auto kCurrentTrack : kTracks) {
195+
//
196+
// Track Selection
197+
if (!kCurrentTrack.isGlobalTrack())
198+
continue;
199+
uHistograms.fill(HIST("QA/Track/Momentum"), kCurrentTrack.dcaZ());
200+
uHistograms.fill(HIST("QA/Track/TMomentum"), kCurrentTrack.pt());
201+
//
202+
// PID Selection
203+
// --- PID QA Kaons
204+
uHistograms.fill(HIST("QA/Kaon/TOF_Nsigma"), kCurrentTrack.pt(),
205+
kCurrentTrack.tofNSigmaKa());
206+
uHistograms.fill(HIST("QA/Kaon/TPC_Nsigma"), kCurrentTrack.pt(),
207+
kCurrentTrack.tpcNSigmaKa());
208+
uHistograms.fill(HIST("QA/Kaon/TOF_TPC_Map"), kCurrentTrack.tofNSigmaKa(),
209+
kCurrentTrack.tpcNSigmaKa());
210+
// --- PID QA Pions
211+
uHistograms.fill(HIST("QA/Pion/TOF_Nsigma"), kCurrentTrack.pt(),
212+
kCurrentTrack.tofNSigmaPi());
213+
uHistograms.fill(HIST("QA/Pion/TPC_Nsigma"), kCurrentTrack.pt(),
214+
kCurrentTrack.tpcNSigmaPi());
215+
uHistograms.fill(HIST("QA/Pion/TOF_TPC_Map"), kCurrentTrack.tofNSigmaPi(),
216+
kCurrentTrack.tpcNSigmaPi());
217+
//
218+
if (uIsKaonSelected(kCurrentTrack)) {
219+
if (kCurrentTrack.sign() > 0)
220+
kPosSelectedKaons.push_back(std::tuple<Float_t, Float_t, Float_t>(
221+
kCurrentTrack.px(), kCurrentTrack.py(), kCurrentTrack.pz()));
222+
else
223+
kNegSelectedKaons.push_back(std::tuple<Float_t, Float_t, Float_t>(
224+
kCurrentTrack.px(), kCurrentTrack.py(), kCurrentTrack.pz()));
225+
}
226+
//
227+
if (uIsPionSelected(kCurrentTrack)) {
228+
if (kCurrentTrack.sign() > 0)
229+
kPosSelectedPions.push_back(std::tuple<Float_t, Float_t, Float_t>(
230+
kCurrentTrack.px(), kCurrentTrack.py(), kCurrentTrack.pz()));
231+
else
232+
kNegSelectedPions.push_back(std::tuple<Float_t, Float_t, Float_t>(
233+
kCurrentTrack.px(), kCurrentTrack.py(), kCurrentTrack.pz()));
234+
}
235+
}
236+
//
237+
// Invariant Mass for Phi
238+
TLorentzVector kPositiveDecayDaughter;
239+
TLorentzVector kNegativeDecayDaughter;
240+
TLorentzVector kResonanceCandidate;
241+
for (auto kPosKaon : kPosSelectedKaons) {
242+
for (auto kNegKaon : kNegSelectedKaons) {
243+
//
244+
kPositiveDecayDaughter.SetXYZM(get<0>(kPosKaon), get<1>(kPosKaon),
245+
get<2>(kPosKaon), .493677);
246+
kNegativeDecayDaughter.SetXYZM(get<0>(kNegKaon), get<1>(kNegKaon),
247+
get<2>(kNegKaon), .493677);
248+
kResonanceCandidate = kPositiveDecayDaughter + kNegativeDecayDaughter;
249+
//
250+
if (kResonanceCandidate.Mag() < 0.90 ||
251+
kResonanceCandidate.Mag() > 1.10)
252+
continue;
253+
if (fabs(kResonanceCandidate.Rapidity()) > 0.5)
254+
continue;
255+
//
256+
uHistograms.fill(HIST("Analysis/Phi/FullInvariantMass"),
257+
kResonanceCandidate.Mag());
258+
}
259+
}
260+
// Invariant Mass for K*
261+
for (auto kPosKaon : kPosSelectedKaons) {
262+
for (auto kNegKaon : kNegSelectedPions) {
263+
//
264+
kPositiveDecayDaughter.SetXYZM(get<0>(kPosKaon), get<1>(kPosKaon),
265+
get<2>(kPosKaon), .493677);
266+
kNegativeDecayDaughter.SetXYZM(get<0>(kNegKaon), get<1>(kNegKaon),
267+
get<2>(kNegKaon), .139570);
268+
kResonanceCandidate = kPositiveDecayDaughter + kNegativeDecayDaughter;
269+
//
270+
if (kResonanceCandidate.Mag() < 0.84 ||
271+
kResonanceCandidate.Mag() > 0.95)
272+
continue;
273+
if (fabs(kResonanceCandidate.Rapidity()) > 0.5)
274+
continue;
275+
//
276+
uHistograms.fill(HIST("Analysis/Kstar/FullInvariantMass"),
277+
kResonanceCandidate.Mag());
278+
}
279+
}
280+
for (auto kPosKaon : kPosSelectedPions) {
281+
for (auto kNegKaon : kNegSelectedKaons) {
282+
//
283+
kPositiveDecayDaughter.SetXYZM(get<0>(kPosKaon), get<1>(kPosKaon),
284+
get<2>(kPosKaon), .139570);
285+
kNegativeDecayDaughter.SetXYZM(get<0>(kNegKaon), get<1>(kNegKaon),
286+
get<2>(kNegKaon), .493677);
287+
kResonanceCandidate = kPositiveDecayDaughter + kNegativeDecayDaughter;
288+
//
289+
if (kResonanceCandidate.Mag() < 0.84 ||
290+
kResonanceCandidate.Mag() > 0.95)
291+
continue;
292+
if (fabs(kResonanceCandidate.Rapidity()) > 0.5)
293+
continue;
294+
//
295+
uHistograms.fill(HIST("Analysis/Kstar/FullInvariantMass"),
296+
kResonanceCandidate.Mag());
297+
}
298+
}
299+
}
300+
//
301+
bool uIsKaonSelected(kTracksTable::iterator const& kCurrentTrack)
302+
{
303+
//
304+
// Utility variables
305+
Bool_t kHasTPC = kCurrentTrack.hasTPC();
306+
Double_t kTPCSigma = kCurrentTrack.tpcNSigmaKa();
307+
Bool_t kHasTOF = kCurrentTrack.hasTOF();
308+
Double_t kTOFSigma = kCurrentTrack.tofNSigmaKa();
309+
Double_t kTMomentum = kCurrentTrack.pt();
310+
//
311+
// Selection
312+
if (!kHasTPC || fabs(kTPCSigma) > kKaonsTPCveto)
313+
return false;
314+
if (!kHasTOF && fabs(kTPCSigma) > kKaonsTPCstda)
315+
return false;
316+
if (kHasTOF && fabs(kTOFSigma) > kKaonsTOFveto)
317+
return false;
318+
//
319+
uHistograms.fill(HIST("QA/Kaon/Selected/TOF_Nsigma"), kTMomentum,
320+
kTOFSigma);
321+
uHistograms.fill(HIST("QA/Kaon/Selected/TPC_Nsigma"), kTMomentum,
322+
kTPCSigma);
323+
uHistograms.fill(HIST("QA/Kaon/Selected/TOF_TPC_Map"), kTOFSigma,
324+
kTPCSigma);
325+
return true;
326+
}
327+
//
328+
bool uIsPionSelected(kTracksTable::iterator const& kCurrentTrack)
329+
{
330+
//
331+
// Utility variables
332+
Bool_t kHasTPC = kCurrentTrack.hasTPC();
333+
Double_t kTPCSigma = kCurrentTrack.tpcNSigmaPi();
334+
Bool_t kHasTOF = kCurrentTrack.hasTOF();
335+
Double_t kTOFSigma = kCurrentTrack.tofNSigmaPi();
336+
Double_t kTMomentum = kCurrentTrack.pt();
337+
//
338+
// Selection
339+
if (!kHasTPC || fabs(kTPCSigma) > kPionsTPCveto)
340+
return false;
341+
if (!kHasTOF && fabs(kTPCSigma) > kPionsTPCstda)
342+
return false;
343+
if (kHasTOF && fabs(kTOFSigma) > kPionsTOFveto)
344+
return false;
345+
//
346+
uHistograms.fill(HIST("QA/Pion/Selected/TOF_Nsigma"), kTMomentum,
347+
kTOFSigma);
348+
uHistograms.fill(HIST("QA/Pion/Selected/TPC_Nsigma"), kTMomentum,
349+
kTPCSigma);
350+
uHistograms.fill(HIST("QA/Pion/Selected/TOF_TPC_Map"), kTOFSigma,
351+
kTPCSigma);
352+
return true;
353+
}
354+
//
355+
bool uIsTrackSelected() { return true; }
356+
};
357+
358+
WorkflowSpec defineDataProcessing(
359+
ConfigContext const& cfgc) // This puts your task in the DPL workflow
360+
{
361+
// Equivalent to the AddTask in AliPhysics
362+
WorkflowSpec workflow{adaptAnalysisTask<rsn_analysis>(cfgc)};
363+
return workflow;
364+
}

0 commit comments

Comments
 (0)