Skip to content

Commit 8a3e9bd

Browse files
akhatunakhatun
andauthored
PWG-UD: Added tasks for tutorials (#7999)
* Added new tasks for Tutorials * Added new tasks for Tutorials --------- Co-authored-by: akhatun <anisa@Anisas-MacBook-Pro.local>
1 parent d71cfad commit 8a3e9bd

4 files changed

Lines changed: 798 additions & 0 deletions

File tree

Tutorials/PWGUD/CMakeLists.txt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,21 @@ o2physics_add_dpl_workflow(udtutorial-04
3939
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
4040
COMPONENT_NAME Analysis)
4141

42+
o2physics_add_dpl_workflow(udtutorial-05
43+
SOURCES UDTutorial_05.cxx
44+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
45+
COMPONENT_NAME Analysis)
46+
47+
o2physics_add_dpl_workflow(udtutorial-06
48+
SOURCES UDTutorial_06.cxx
49+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
50+
COMPONENT_NAME Analysis)
51+
52+
o2physics_add_dpl_workflow(udtutorial-07
53+
SOURCES UDTutorial_07.cxx
54+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
55+
COMPONENT_NAME Analysis)
56+
57+
58+
59+

Tutorials/PWGUD/UDTutorial_05.cxx

Lines changed: 318 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,318 @@
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+
13+
#include "iostream"
14+
#include "TLorentzVector.h"
15+
#include "TDatabasePDG.h"
16+
17+
#include "Framework/runDataProcessing.h"
18+
#include "Framework/AnalysisTask.h"
19+
#include "Framework/AnalysisDataModel.h"
20+
#include "PWGUD/DataModel/UDTables.h"
21+
#include "PWGUD/Core/SGSelector.h"
22+
#include "PWGUD/Core/SGTrackSelector.h"
23+
24+
// using namespace std;
25+
using namespace o2;
26+
using namespace o2::aod;
27+
using namespace o2::framework;
28+
using namespace o2::framework::expressions;
29+
30+
/// \brief Example task to study two pions candidates using SG derive data
31+
/// \author Anisa Khatun
32+
/// \date 10.10.2024
33+
34+
// Struct to define the analysis task
35+
struct UDTutorial05 {
36+
// SGSelector object to manage track and collision selections
37+
SGSelector sgSelector;
38+
39+
Configurable<float> FV0_cut{"FV0", 100., "FV0A threshold"};
40+
Configurable<float> FT0A_cut{"FT0A", 100., "FT0A threshold"};
41+
Configurable<float> FT0C_cut{"FT0C", 50., "FT0C threshold"};
42+
Configurable<float> FDDA_cut{"FDDA", 10000., "FDDA threshold"};
43+
Configurable<float> FDDC_cut{"FDDC", 10000., "FDDC threshold"};
44+
Configurable<float> ZDC_cut{"ZDC", 10., "ZDC threshold"};
45+
Configurable<float> gap_Side{"gap", 2, "gap selection"};
46+
47+
// Track Selections
48+
Configurable<float> PV_cut{"PV_cut", 1.0, "Use Only PV tracks"};
49+
Configurable<float> dcaZ_cut{"dcaZ_cut", 2.0, "dcaZ cut"};
50+
Configurable<float> dcaXY_cut{"dcaXY_cut", 0.0, "dcaXY cut (0 for Pt-function)"};
51+
Configurable<float> tpcChi2_cut{"tpcChi2_cut", 4, "Max tpcChi2NCl"};
52+
Configurable<float> tpcNClsFindable_cut{"tpcNClsFindable_cut", 70, "Min tpcNClsFindable"};
53+
Configurable<float> itsChi2_cut{"itsChi2_cut", 36, "Max itsChi2NCl"};
54+
Configurable<float> eta_cut{"eta_cut", 0.9, "Track Pseudorapidity"};
55+
Configurable<float> pt_cut{"pt_cut", 0.01, "Track Pt"};
56+
Configurable<float> TPC_cluster{"TPC_cluster", 50, "No.of TPC cluster"};
57+
58+
// Kinmatic cuts
59+
Configurable<float> PID_cut{"PID_cut", 5, "TPC PID"};
60+
Configurable<float> Rap_cut{"Rap_cut", 0.9, "Track rapidity"};
61+
Configurable<float> Mass_Max{"Mass_Max", 10, "Invariant Mass range high"};
62+
Configurable<float> Mass_Min{"Mass_Min", 0, "Invariant Mass range low"};
63+
Configurable<float> Pt_coherent{"Pt_coherent", 0.15, "Coherent selection"};
64+
65+
// defining histograms using histogram registry
66+
HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject};
67+
68+
//-----------------------------------------------------------------------------------------------------------------------
69+
void init(o2::framework::InitContext&)
70+
{
71+
72+
registry.add("GapSide", "Gap Side; Entries", kTH1F, {{4, -1.5, 2.5}});
73+
registry.add("TrueGapSide", "Gap Side; Entries", kTH1F, {{4, -1.5, 2.5}});
74+
75+
// Fill counter to see effect of each selection criteria
76+
auto hSelectionCounter = registry.add<TH1>("hSelectionCounter", "hSelectionCounter;;NEvents", HistType::kTH1I, {{20, 0., 20.}});
77+
78+
TString SelectionCuts[16] = {"NoSelection", "gapside", "goodtracks", "truegap", "2collcontrib", "2goodtrk", "TPCPID", "Rap_cut", "unlikesign", "mass_cut", "coherent", "incoherent", "likesign", "mass_cut", "coherent", "incoherent"};
79+
80+
for (int i = 0; i < 16; i++) {
81+
hSelectionCounter->GetXaxis()->SetBinLabel(i + 1, SelectionCuts[i].Data());
82+
}
83+
// tracks
84+
registry.add("hTracks", "N_{tracks}", kTH1F, {{100, -0.5, 99.5}});
85+
registry.add("hTracksPions", "N_{tracks}", kTH1F, {{100, -0.5, 99.5}});
86+
registry.add("TwoPion/h2TracksPions", "N_{tracks}", kTH1F, {{100, -0.5, 99.5}});
87+
88+
registry.add("hdEdx", "p vs dE/dx Signal", kTH2F, {{100, 0.0, 3.0}, {100, 0.0, 200.0}});
89+
registry.add("hdEdxPion", "p_{#pi} vs dE/dx Signal", kTH2F, {{100, 0.0, 3.0}, {100, 0.0, 200.0}});
90+
91+
registry.add("TwoPion/hNsigPi1vsPi2", "NSigmaPi(t1) vs NSigmapi (t2);n#sigma_{1};n#sigma_{2}", kTH2F, {{100, -15., 15.}, {100, -15., 15}});
92+
registry.add("TwoPion/hNsigEl1vsEl2", "NSigmaEl(t1) vs NSigmaEl (t2);n#sigma_{1};n#sigma_{2}", kTH2F, {{100, -15., 15.}, {100, -15., 15}});
93+
registry.add("TwoPion/hNsigPivsPt1", "Pt vs NSigmaPi (t1);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
94+
registry.add("TwoPion/hNsigPivsPt2", "Pt vs NSigmaPi (t2);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
95+
registry.add("TwoPion/hNsigElvsPt1", "Pt vs NSigmaEl (t1);#it{p_{t}}, GeV/c;n#sigma_{#e}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
96+
registry.add("TwoPion/hNsigElvsPt2", "Pt vs NSigmaEl (t2);#it{p_{t}}, GeV/c;n#sigma_{#e}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
97+
registry.add("TwoPion/hNsigMuvsPt1", "Pt vs NSigmaMu (t1);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
98+
registry.add("TwoPion/hNsigMuvsPt2", "Pt vs NSigmaMu (t2);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
99+
100+
registry.add("TwoPion/hPtsingle_track1", "Pt t1;#it{p_{t}}, GeV/c;", kTH1F, {{600, 0., 3.}});
101+
registry.add("TwoPion/hPtsingle_track2", "Pt t2;#it{p_{t}}, GeV/c;", kTH1F, {{600, 0., 3.}});
102+
registry.add("TwoPion/hEta_t1", "Eta of t1;#it{#eta};", kTH1F, {{100, -5., 5.}});
103+
registry.add("TwoPion/hEta_t2", "Eta of t2;#it{#eta};", kTH1F, {{100, -5., 5.}});
104+
registry.add("TwoPion/hP1", "P vs TPC signal;#it{P_{track}}, GeV/c; signal_{TPC} t1", kTH2F, {{100, 0., 2.}, {300, 0, 150}});
105+
registry.add("TwoPion/hTPCsig", "TPC signal;signal_{TPC} t2; signal_{TPC} t2", kTH2F, {{300, 0., 150.}, {300, 0, 150}});
106+
registry.add("TwoPion/hP2", "P vs TPC signal;#it{P_{track}}, GeV/c; signal_{TPC} t1", kTH2F, {{100, 0., 2.}, {300, 0, 150}});
107+
registry.add("TwoPion/hTPCsig1", "TPC signal;signal_{TPC} t2; signal_{TPC} t2", kTH2F, {{300, 0., 150.}, {300, 0, 150}});
108+
109+
registry.add("TwoPion/hMassLike", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
110+
registry.add("TwoPion/hMassUnlike", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
111+
registry.add("TwoPion/Coherent/hMassUnlikeCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
112+
registry.add("TwoPion/Coherent/hMassLikeCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
113+
registry.add("TwoPion/Incoherent/hMassUnlikeInCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
114+
registry.add("TwoPion/Incoherent/hMassLikeInCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
115+
116+
registry.add("TwoPion/hPt", "Pt;#it{p_{t}}, GeV/c;", kTH1D, {{1000, 0., 10.}});
117+
registry.add("TwoPion/hPtLike", "Pt;#it{p_{t}}, GeV/c;", kTH1D, {{1000, 0., 10.}});
118+
registry.add("TwoPion/hEta", "Eta;#it{#eta};", kTH1F, {{500, -10., 10.}});
119+
registry.add("TwoPion/hRap", "Rapidity;#it{y};", kTH1F, {{500, -10., 10.}});
120+
registry.add("TwoPion/hPhiSystem", "Phi;#it{#Phi};", kTH1F, {{250, 0. * TMath::Pi(), 2. * TMath::Pi()}});
121+
registry.add("TwoPion/hMPt", "Inv.M vs Pt;M, GeV/c^{2};#it{P_{t}}, GeV/c;", kTH2F, {{100, 0., 10.}, {100, 0., 10.}});
122+
}
123+
124+
using udtracks = soa::Join<aod::UDTracks, aod::UDTracksExtra, aod::UDTracksPID>;
125+
using udtracksfull = soa::Join<aod::UDTracks, aod::UDTracksPID, aod::UDTracksExtra, aod::UDTracksFlags, aod::UDTracksDCA>;
126+
127+
using UDCollisionsFull = soa::Join<aod::UDCollisions, aod::SGCollisions, aod::UDCollisionsSels, aod::UDZdcsReduced>;
128+
129+
//__________________________________________________________________________
130+
// Main process
131+
void process(UDCollisionsFull::iterator const& collision, udtracksfull const& tracks)
132+
{
133+
// No selection criteria
134+
registry.fill(HIST("hSelectionCounter"), 0);
135+
136+
// Accessing gap sides
137+
int gapSide = collision.gapSide();
138+
if (gapSide < 0 || gapSide > 2)
139+
return;
140+
141+
registry.fill(HIST("hSelectionCounter"), 1);
142+
143+
// Accessing FIT information for further exclusivity and/or inclusivity
144+
float FIT_cut[5] = {FV0_cut, FT0A_cut, FT0C_cut, FDDA_cut, FDDC_cut};
145+
int truegapSide = sgSelector.trueGap(collision, FIT_cut[0], FIT_cut[1], FIT_cut[2], ZDC_cut);
146+
147+
// Intiating track parameters to select good tracks, values to be optimized in the configurables, parameters will be taken from SGtrackselector.h task included in the header
148+
std::vector<float> parameters = {PV_cut, dcaZ_cut, dcaXY_cut, tpcChi2_cut, tpcNClsFindable_cut, itsChi2_cut, eta_cut, pt_cut};
149+
150+
registry.fill(HIST("GapSide"), gapSide);
151+
registry.fill(HIST("TrueGapSide"), truegapSide);
152+
153+
// Gap side to be selected in the configuables
154+
gapSide = truegapSide;
155+
156+
if (gapSide == gap_Side) {
157+
158+
registry.fill(HIST("hSelectionCounter"), 2);
159+
160+
//____________________________________________________________________________________
161+
162+
// Create LorentzVector to store all tracks, Pion tracks and TPC Pion PID
163+
std::vector<TLorentzVector> allTracks;
164+
std::vector<TLorentzVector> onlyPionTracks;
165+
std::vector<float> onlyPionSigma;
166+
std::vector<decltype(tracks.begin())> rawPionTracks;
167+
TLorentzVector p;
168+
169+
registry.fill(HIST("hTracks"), tracks.size());
170+
171+
for (auto t : tracks) {
172+
// Apply good track selection criteria
173+
if (!trackselector(t, parameters))
174+
continue;
175+
176+
double dEdx = t.tpcSignal();
177+
178+
registry.fill(HIST("hdEdx"), t.tpcInnerParam() / t.sign(), dEdx);
179+
180+
// Creating Lorenz vector to store raw tracks and piontracks
181+
TLorentzVector a;
182+
a.SetXYZM(t.px(), t.py(), t.pz(), o2::constants::physics::MassPionCharged);
183+
allTracks.push_back(a);
184+
185+
// Apply TPC pion sigma
186+
auto nSigmaPi = t.tpcNSigmaPi();
187+
if (fabs(nSigmaPi) < PID_cut) {
188+
onlyPionTracks.push_back(a);
189+
onlyPionSigma.push_back(nSigmaPi);
190+
rawPionTracks.push_back(t);
191+
registry.fill(HIST("hdEdxPion"), t.tpcInnerParam() / t.sign(), dEdx);
192+
}
193+
}
194+
195+
registry.fill(HIST("hTracksPions"), onlyPionTracks.size());
196+
//_____________________________________
197+
// Adding all onlypiontracks
198+
for (auto pion : onlyPionTracks) {
199+
p += pion;
200+
}
201+
202+
//_____________________________________
203+
// Selecting collisions with Two PV contributors
204+
if (collision.numContrib() == 2) {
205+
206+
registry.fill(HIST("hSelectionCounter"), 3);
207+
208+
// Selecting only Two good tracks
209+
if ((rawPionTracks.size() == 2) && (onlyPionTracks.size() == 2)) {
210+
211+
registry.fill(HIST("hSelectionCounter"), 4);
212+
213+
registry.fill(HIST("TwoPion/h2TracksPions"), onlyPionTracks.size());
214+
215+
registry.fill(HIST("TwoPion/hNsigPivsPt1"), onlyPionTracks[0].Pt(), rawPionTracks[0].tpcNSigmaPi());
216+
registry.fill(HIST("TwoPion/hNsigPivsPt2"), onlyPionTracks[1].Pt(), rawPionTracks[1].tpcNSigmaPi());
217+
registry.fill(HIST("TwoPion/hTPCsig"), rawPionTracks[0].tpcSignal(), rawPionTracks[1].tpcSignal());
218+
registry.fill(HIST("TwoPion/hNsigPi1vsPi2"), rawPionTracks[0].tpcNSigmaPi(), rawPionTracks[1].tpcNSigmaPi());
219+
220+
// Make sure two good tracks are with TPC pion sigma limit
221+
if ((onlyPionSigma[0] * onlyPionSigma[0] + onlyPionSigma[1] * onlyPionSigma[1]) > (PID_cut * PID_cut)) {
222+
return;
223+
}
224+
225+
registry.fill(HIST("hSelectionCounter"), 5);
226+
227+
// Rapidity of midrapidity acceptance
228+
if ((p.Rapidity() < -Rap_cut) || (p.Rapidity() > Rap_cut)) {
229+
return;
230+
}
231+
232+
registry.fill(HIST("hSelectionCounter"), 6);
233+
234+
// Two oppsotite sign tracks
235+
if (rawPionTracks[0].sign() != rawPionTracks[1].sign()) {
236+
237+
registry.fill(HIST("hSelectionCounter"), 7);
238+
registry.fill(HIST("TwoPion/hMassUnlike"), p.M());
239+
240+
// Flexible mass limits, can be selected in the configurable
241+
if ((p.M() > Mass_Min) && (p.M() < Mass_Max)) {
242+
243+
registry.fill(HIST("hSelectionCounter"), 8);
244+
245+
registry.fill(HIST("TwoPion/hPt"), p.Pt());
246+
registry.fill(HIST("TwoPion/hEta"), p.Eta());
247+
registry.fill(HIST("TwoPion/hRap"), p.Rapidity());
248+
registry.fill(HIST("TwoPion/hPhiSystem"), p.Phi());
249+
registry.fill(HIST("TwoPion/hMPt"), p.M(), p.Pt());
250+
251+
// flexible pt limit for selecting coherent Rho(0)
252+
if (p.Pt() < Pt_coherent) {
253+
254+
registry.fill(HIST("hSelectionCounter"), 9);
255+
256+
// Quality Control plots after coherent Rho(0) selection
257+
registry.fill(HIST("TwoPion/hEta_t1"), onlyPionTracks[0].Eta());
258+
registry.fill(HIST("TwoPion/hEta_t2"), onlyPionTracks[1].Eta());
259+
registry.fill(HIST("TwoPion/hPtsingle_track1"), onlyPionTracks[0].Pt());
260+
registry.fill(HIST("TwoPion/hPtsingle_track2"), onlyPionTracks[1].Pt());
261+
262+
registry.fill(HIST("TwoPion/hNsigMuvsPt1"), onlyPionTracks[0].Pt(), rawPionTracks[0].tpcNSigmaPi());
263+
registry.fill(HIST("TwoPion/hNsigMuvsPt2"), onlyPionTracks[1].Pt(), rawPionTracks[1].tpcNSigmaPi());
264+
registry.fill(HIST("TwoPion/hNsigElvsPt1"), onlyPionTracks[0].Pt(), rawPionTracks[0].tpcNSigmaEl());
265+
registry.fill(HIST("TwoPion/hNsigElvsPt2"), onlyPionTracks[1].Pt(), rawPionTracks[1].tpcNSigmaEl());
266+
registry.fill(HIST("TwoPion/hNsigEl1vsEl2"), rawPionTracks[0].tpcNSigmaPi(), rawPionTracks[1].tpcNSigmaPi());
267+
268+
registry.fill(HIST("TwoPion/hP1"), onlyPionTracks[0].P(), rawPionTracks[0].tpcSignal());
269+
registry.fill(HIST("TwoPion/hP2"), onlyPionTracks[1].P(), rawPionTracks[1].tpcSignal());
270+
registry.fill(HIST("TwoPion/hTPCsig1"), rawPionTracks[0].tpcSignal(), rawPionTracks[1].tpcSignal());
271+
272+
registry.fill(HIST("TwoPion/Coherent/hMassUnlikeCoherent"), p.M());
273+
}
274+
// Incoherent Rho(0) selection
275+
if (p.Pt() > Pt_coherent) {
276+
registry.fill(HIST("hSelectionCounter"), 10);
277+
registry.fill(HIST("TwoPion/Incoherent/hMassUnlikeInCoherent"), p.M());
278+
}
279+
}
280+
}
281+
282+
// Same charge particles
283+
if (rawPionTracks[0].sign() == rawPionTracks[1].sign()) {
284+
285+
registry.fill(HIST("hSelectionCounter"), 11);
286+
registry.fill(HIST("TwoPion/hMassLike"), p.M());
287+
288+
// Mass limit
289+
if ((p.M() > Mass_Min) && (p.M() < Mass_Max)) {
290+
291+
registry.fill(HIST("hSelectionCounter"), 12);
292+
registry.fill(HIST("TwoPion/hPtLike"), p.Pt());
293+
294+
// Coherent Rho(0) selection
295+
if (p.Pt() < Pt_coherent) {
296+
297+
registry.fill(HIST("hSelectionCounter"), 13);
298+
registry.fill(HIST("TwoPion/Coherent/hMassLikeCoherent"), p.M());
299+
}
300+
// Incoherent Rho(0) selection
301+
if (p.Pt() > Pt_coherent) {
302+
303+
registry.fill(HIST("hSelectionCounter"), 14);
304+
registry.fill(HIST("TwoPion/Incoherent/hMassLikeInCoherent"), p.M());
305+
}
306+
}
307+
}
308+
}
309+
}
310+
}
311+
}
312+
};
313+
314+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
315+
{
316+
return WorkflowSpec{
317+
adaptAnalysisTask<UDTutorial05>(cfgc, TaskName{"udtutorial05"})};
318+
}

0 commit comments

Comments
 (0)