Skip to content

Commit 6fb224b

Browse files
Add files via upload
1 parent 53487ae commit 6fb224b

File tree

2 files changed

+335
-2
lines changed

2 files changed

+335
-2
lines changed

PWGUD/Tasks/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ o2physics_add_dpl_workflow(upc-test-rct-tables
264264
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
265265
COMPONENT_NAME Analysis)
266266

267-
o2physics_add_dpl_workflow(sg-exclusive-jpsi-cb
268-
SOURCES sgExclusiveJpsiCB.cxx
267+
o2physics_add_dpl_workflow(sg-exclusive-jpsi-midrapidity
268+
SOURCES sgExclusiveJpsiMidrapidity.cxx
269269
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
270270
COMPONENT_NAME Analysis)
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+
/// \brief Task to study two pions candidates using SG derive data
13+
/// \author Levi Van Ryder (based on Anisa Khatun's UD Tutorial 5 example)
14+
/// \file sgExclusiveJpsiMidrapidity.cxx
15+
16+
#include <cmath>
17+
#include <cstdlib>
18+
#include <string>
19+
#include <vector>
20+
#include "Math/Vector4D.h"
21+
#include "TMath.h"
22+
23+
#include "Framework/runDataProcessing.h"
24+
#include "Framework/AnalysisTask.h"
25+
#include "Framework/AnalysisDataModel.h"
26+
#include "PWGUD/DataModel/UDTables.h"
27+
#include "PWGUD/Core/SGSelector.h"
28+
#include "PWGUD/Core/SGTrackSelector.h"
29+
30+
using namespace o2;
31+
using namespace o2::aod;
32+
using namespace o2::framework;
33+
using namespace o2::framework::expressions;
34+
using LorentzVector = ROOT::Math::PxPyPzMVector;
35+
36+
// Struct to define the analysis task
37+
struct SGExclusiveJpsiMidrapidity {
38+
// SGSelector object to manage track and collision selections
39+
SGSelector sgSelector;
40+
41+
// Number of Selection cuts
42+
const int numSelectionCuts = 16;
43+
44+
// Gapside rejection
45+
const int gapSideLow = 0;
46+
const int gapSideHigh = 2;
47+
48+
// Numbers for selections
49+
const int two = 2;
50+
51+
Configurable<float> fv0Cut{"fv0Cut", 100., "fv0aThreshold"};
52+
Configurable<float> ft0aCut{"ft0aCut", 100., "ft0aThreshold"};
53+
Configurable<float> ft0cCut{"ft0cCut", 50., "ft0cThreshold"};
54+
Configurable<float> fddaCut{"fddaCut", 10000., "fddaThreshold"};
55+
Configurable<float> fddcCut{"fddcCut", 10000., "fddcThreshold"};
56+
Configurable<float> zdcCut{"zdcCut", 10., "zdcThreshold"};
57+
Configurable<float> gapSide{"gapSide", 2, "gapSelection"};
58+
59+
// Track Selections
60+
Configurable<float> pvCut{"pvCut", 1.0, "Use Only PV tracks"};
61+
Configurable<float> dcazCut{"dcazCut", 2.0, "dcaZ cut"};
62+
Configurable<float> dcaxyCut{"dcaxyCut", 0.0, "dcaXY cut (0 for Pt-function)"};
63+
Configurable<float> tpcChi2Cut{"tpcChi2Cut", 4, "Max tpcChi2NCl"};
64+
Configurable<float> tpcNClsFindableCut{"tpcNClsFindableCut", 70, "Min tpcNClsFindable"};
65+
Configurable<float> itsChi2Cut{"itsChi2Cut", 36, "Max itsChi2NCl"};
66+
Configurable<float> etaCut{"etaCut", 0.9, "Track Pseudorapidity"};
67+
Configurable<float> ptCut{"ptCut", 0.01, "Track Pt"};
68+
Configurable<float> tpcCluster{"tpcCluster", 50, "No.of TPC cluster"};
69+
70+
// Kinematic cuts
71+
Configurable<float> pidCut{"pidCut", 5, "TPC PID"};
72+
Configurable<float> rapCut{"rapCut", 0.9, "Track rapidity"};
73+
Configurable<float> massMax{"massMax", 10, "Invariant Mass range high"};
74+
Configurable<float> massMin{"massMin", 0, "Invariant Mass range low"};
75+
Configurable<float> ptCoherent{"ptCoherent", 0.15, "Coherent selection"};
76+
77+
// defining histograms using histogram registry
78+
HistogramRegistry registry{"registry", {}, OutputObjHandlingPolicy::AnalysisObject};
79+
80+
//-----------------------------------------------------------------------------------------------------------------------
81+
void init(o2::framework::InitContext&)
82+
{
83+
84+
registry.add("GapSide", "Gap Side; Entries", kTH1F, {{4, -1.5, 2.5}});
85+
registry.add("TrueGapSide", "Gap Side; Entries", kTH1F, {{4, -1.5, 2.5}});
86+
87+
// Fill counter to see effect of each selection criteria
88+
auto hSelectionCounter = registry.add<TH1>("hSelectionCounter", "hSelectionCounter;;NEvents", HistType::kTH1I, {{20, 0., 20.}});
89+
90+
TString SelectionCuts[16] = {"NoSelection", "gapside", "goodtracks", "truegap", "2collcontrib", "2goodtrk", "TPCPID", "rapCut", "unlikesign", "mass_cut", "coherent", "incoherent", "likesign", "mass_cut", "coherent", "incoherent"};
91+
92+
for (int i = 0; i < numSelectionCuts; i++) {
93+
hSelectionCounter->GetXaxis()->SetBinLabel(i + 1, SelectionCuts[i].Data());
94+
}
95+
// tracks
96+
registry.add("hTracks", "N_{tracks}", kTH1F, {{100, -0.5, 99.5}});
97+
registry.add("hTracksPions", "N_{tracks}", kTH1F, {{100, -0.5, 99.5}});
98+
registry.add("TwoPion/h2TracksPions", "N_{tracks}", kTH1F, {{100, -0.5, 99.5}});
99+
100+
registry.add("hdEdx", "p vs dE/dx Signal", kTH2F, {{100, 0.0, 3.0}, {100, 0.0, 200.0}});
101+
registry.add("hdEdxPion", "p_{#pi} vs dE/dx Signal", kTH2F, {{100, 0.0, 3.0}, {100, 0.0, 200.0}});
102+
103+
registry.add("TwoPion/hNsigPi1vsPi2", "NSigmaPi(t1) vs NSigmapi (t2);n#sigma_{1};n#sigma_{2}", kTH2F, {{100, -15., 15.}, {100, -15., 15}});
104+
registry.add("TwoPion/hNsigEl1vsEl2", "NSigmaEl(t1) vs NSigmaEl (t2);n#sigma_{1};n#sigma_{2}", kTH2F, {{100, -15., 15.}, {100, -15., 15}});
105+
registry.add("TwoPion/hNsigPivsPt1", "Pt vs NSigmaPi (t1);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
106+
registry.add("TwoPion/hNsigPivsPt2", "Pt vs NSigmaPi (t2);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
107+
registry.add("TwoPion/hNsigElvsPt1", "Pt vs NSigmaEl (t1);#it{p_{t}}, GeV/c;n#sigma_{#e}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
108+
registry.add("TwoPion/hNsigElvsPt2", "Pt vs NSigmaEl (t2);#it{p_{t}}, GeV/c;n#sigma_{#e}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
109+
registry.add("TwoPion/hNsigMuvsPt1", "Pt vs NSigmaMu (t1);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
110+
registry.add("TwoPion/hNsigMuvsPt2", "Pt vs NSigmaMu (t2);#it{p_{t}}, GeV/c;n#sigma_{#pi}", kTH2F, {{100, 0., 2.5}, {100, -15., 15}});
111+
112+
registry.add("TwoPion/hPtsingle_track1", "Pt t1;#it{p_{t}}, GeV/c;", kTH1F, {{600, 0., 3.}});
113+
registry.add("TwoPion/hPtsingle_track2", "Pt t2;#it{p_{t}}, GeV/c;", kTH1F, {{600, 0., 3.}});
114+
registry.add("TwoPion/hEta_t1", "Eta of t1;#it{#eta};", kTH1F, {{100, -5., 5.}});
115+
registry.add("TwoPion/hEta_t2", "Eta of t2;#it{#eta};", kTH1F, {{100, -5., 5.}});
116+
registry.add("TwoPion/hP1", "P vs TPC signal;#it{P_{track}}, GeV/c; signal_{TPC} t1", kTH2F, {{100, 0., 2.}, {300, 0, 150}});
117+
registry.add("TwoPion/hTPCsig", "TPC signal;signal_{TPC} t2; signal_{TPC} t2", kTH2F, {{300, 0., 150.}, {300, 0, 150}});
118+
registry.add("TwoPion/hP2", "P vs TPC signal;#it{P_{track}}, GeV/c; signal_{TPC} t1", kTH2F, {{100, 0., 2.}, {300, 0, 150}});
119+
registry.add("TwoPion/hTPCsig1", "TPC signal;signal_{TPC} t2; signal_{TPC} t2", kTH2F, {{300, 0, 150.}, {300, 0, 150}});
120+
121+
registry.add("TwoPion/hMassLike", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
122+
registry.add("TwoPion/hMassUnlike", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
123+
registry.add("TwoPion/Coherent/hMassUnlikeCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
124+
registry.add("TwoPion/Coherent/hMassLikeCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
125+
registry.add("TwoPion/Incoherent/hMassUnlikeInCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
126+
registry.add("TwoPion/Incoherent/hMassLikeInCoherent", "m_{#pi#pi} [GeV/#it{c}^{2}]", kTH1F, {{20000, 0., 20.}});
127+
128+
registry.add("TwoPion/hPt", "Pt;#it{p_{t}}, GeV/c;", kTH1D, {{1000, 0., 10.}});
129+
registry.add("TwoPion/hPtLike", "Pt;#it{p_{t}}, GeV/c;", kTH1D, {{1000, 0., 10.}});
130+
registry.add("TwoPion/hEta", "Eta;#it{#eta};", kTH1F, {{500, -10., 10.}});
131+
registry.add("TwoPion/hRap", "Rapidity;#it{y};", kTH1F, {{500, -10., 10.}});
132+
registry.add("TwoPion/hPhiSystem", "Phi;#it{#Phi};", kTH1F, {{250, 0. * TMath::Pi(), 2. * TMath::Pi()}});
133+
registry.add("TwoPion/hMPt", "Inv.M vs Pt;M, GeV/c^{2};#it{P_{t}}, GeV/c;", kTH2F, {{100, 0., 10.}, {100, 0., 10.}});
134+
}
135+
136+
using udtracks = soa::Join<aod::UDTracks, aod::UDTracksExtra, aod::UDTracksPID>;
137+
using udtracksfull = soa::Join<aod::UDTracks, aod::UDTracksPID, aod::UDTracksExtra, aod::UDTracksFlags, aod::UDTracksDCA>;
138+
139+
using UDCollisionsFull = soa::Join<aod::UDCollisions, aod::SGCollisions, aod::UDCollisionsSels, aod::UDZdcsReduced>;
140+
141+
//__________________________________________________________________________
142+
// Main process
143+
void process(UDCollisionsFull::iterator const& collision, udtracksfull const& tracks)
144+
{
145+
// No selection criteria
146+
registry.fill(HIST("hSelectionCounter"), 0);
147+
148+
// Accessing gap sides
149+
int gapSide = collision.gapSide();
150+
if (gapSide < gapSideLow || gapSide > gapSideHigh)
151+
return;
152+
153+
registry.fill(HIST("hSelectionCounter"), 1);
154+
155+
// Accessing FIT information for further exclusivity and/or inclusivity
156+
float FIT_cut[5] = {fv0Cut, ft0aCut, ft0cCut, fddaCut, fddcCut};
157+
int truegapSide = sgSelector.trueGap(collision, FIT_cut[0], FIT_cut[1], FIT_cut[2], zdcCut);
158+
159+
// Initiating 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
160+
std::vector<float> parameters = {pvCut, dcazCut, dcaxyCut, tpcChi2Cut, tpcNClsFindableCut, itsChi2Cut, etaCut, ptCut};
161+
162+
registry.fill(HIST("GapSide"), gapSide);
163+
registry.fill(HIST("TrueGapSide"), truegapSide);
164+
165+
// Gap side to be selected in the configurables
166+
gapSide = truegapSide;
167+
168+
if (gapSide == gapSide) {
169+
170+
registry.fill(HIST("hSelectionCounter"), 2);
171+
172+
if(collision.flags()!=1) return; //UPC setting vs std setting
173+
//____________________________________________________________________________________
174+
175+
// Create LorentzVector to store all tracks, Pion tracks and TPC Pion PID
176+
std::vector<LorentzVector> allTracks;
177+
std::vector<LorentzVector> onlyPionTracks;
178+
std::vector<float> onlyPionSigma;
179+
std::vector<decltype(tracks.begin())> rawPionTracks;
180+
181+
// initialize pair 4-vector to zero before accumulation
182+
LorentzVector p(0.0, 0.0, 0.0, 0.0);
183+
184+
registry.fill(HIST("hTracks"), tracks.size());
185+
186+
for (const auto& t : tracks) {
187+
// Apply good track selection criteria
188+
if (!trackselector(t, parameters))
189+
continue;
190+
191+
double dEdx = t.tpcSignal();
192+
193+
registry.fill(HIST("hdEdx"), t.tpcInnerParam() / t.sign(), dEdx);
194+
195+
// Create Lorentz vector for this track (use constructor, portable)
196+
LorentzVector a(t.px(), t.py(), t.pz(), o2::constants::physics::MassPionCharged);
197+
allTracks.push_back(a);
198+
199+
// Apply TPC pion sigma
200+
auto nSigmaPi = t.tpcNSigmaPi();
201+
if (std::fabs(nSigmaPi) < pidCut) {
202+
onlyPionTracks.push_back(a);
203+
onlyPionSigma.push_back(nSigmaPi);
204+
rawPionTracks.push_back(t);
205+
registry.fill(HIST("hdEdxPion"), t.tpcInnerParam() / t.sign(), dEdx);
206+
}
207+
}
208+
209+
registry.fill(HIST("hTracksPions"), onlyPionTracks.size());
210+
211+
//_____________________________________
212+
// Add all onlyPionTracks into p
213+
for (const auto& pion : onlyPionTracks) {
214+
p += pion;
215+
}
216+
217+
//_____________________________________
218+
// Selecting collisions with Two PV contributors
219+
if (collision.numContrib() == two) {
220+
221+
registry.fill(HIST("hSelectionCounter"), 3);
222+
223+
// Selecting only Two good tracks
224+
if ((rawPionTracks.size() == two) && (onlyPionTracks.size() == two)) {
225+
226+
registry.fill(HIST("hSelectionCounter"), 4);
227+
228+
registry.fill(HIST("TwoPion/h2TracksPions"), onlyPionTracks.size());
229+
230+
registry.fill(HIST("TwoPion/hNsigPivsPt1"), onlyPionTracks[0].Pt(), rawPionTracks[0].tpcNSigmaPi());
231+
registry.fill(HIST("TwoPion/hNsigPivsPt2"), onlyPionTracks[1].Pt(), rawPionTracks[1].tpcNSigmaPi());
232+
registry.fill(HIST("TwoPion/hTPCsig"), rawPionTracks[0].tpcSignal(), rawPionTracks[1].tpcSignal());
233+
registry.fill(HIST("TwoPion/hNsigPi1vsPi2"), rawPionTracks[0].tpcNSigmaPi(), rawPionTracks[1].tpcNSigmaPi());
234+
235+
// Make sure two good tracks are within TPC pion sigma limit
236+
if ((onlyPionSigma[0] * onlyPionSigma[0] + onlyPionSigma[1] * onlyPionSigma[1]) > (pidCut * pidCut)) {
237+
return;
238+
}
239+
240+
registry.fill(HIST("hSelectionCounter"), 5);
241+
242+
// Rapidity of midrapidity acceptance
243+
if ((p.Rapidity() < -rapCut) || (p.Rapidity() > rapCut)) {
244+
return;
245+
}
246+
247+
registry.fill(HIST("hSelectionCounter"), 6);
248+
249+
// Two opposite sign tracks
250+
if (rawPionTracks[0].sign() != rawPionTracks[1].sign()) {
251+
252+
registry.fill(HIST("hSelectionCounter"), 7);
253+
registry.fill(HIST("TwoPion/hMassUnlike"), p.M());
254+
255+
// Flexible mass limits, can be selected in the configurable
256+
if ((p.M() > massMin) && (p.M() < massMax)) {
257+
258+
registry.fill(HIST("hSelectionCounter"), 8);
259+
260+
registry.fill(HIST("TwoPion/hPt"), p.Pt());
261+
registry.fill(HIST("TwoPion/hEta"), p.Eta());
262+
registry.fill(HIST("TwoPion/hRap"), p.Rapidity());
263+
registry.fill(HIST("TwoPion/hPhiSystem"), p.Phi());
264+
registry.fill(HIST("TwoPion/hMPt"), p.M(), p.Pt());
265+
266+
// flexible pt limit for selecting coherent Rho(0)
267+
if (p.Pt() < ptCoherent) {
268+
269+
registry.fill(HIST("hSelectionCounter"), 9);
270+
271+
// Quality Control plots after coherent Rho(0) selection
272+
registry.fill(HIST("TwoPion/hEta_t1"), onlyPionTracks[0].Eta());
273+
registry.fill(HIST("TwoPion/hEta_t2"), onlyPionTracks[1].Eta());
274+
registry.fill(HIST("TwoPion/hPtsingle_track1"), onlyPionTracks[0].Pt());
275+
registry.fill(HIST("TwoPion/hPtsingle_track2"), onlyPionTracks[1].Pt());
276+
277+
registry.fill(HIST("TwoPion/hNsigMuvsPt1"), onlyPionTracks[0].Pt(), rawPionTracks[0].tpcNSigmaPi());
278+
registry.fill(HIST("TwoPion/hNsigMuvsPt2"), onlyPionTracks[1].Pt(), rawPionTracks[1].tpcNSigmaPi());
279+
registry.fill(HIST("TwoPion/hNsigElvsPt1"), onlyPionTracks[0].Pt(), rawPionTracks[0].tpcNSigmaEl());
280+
registry.fill(HIST("TwoPion/hNsigElvsPt2"), onlyPionTracks[1].Pt(), rawPionTracks[1].tpcNSigmaEl());
281+
registry.fill(HIST("TwoPion/hNsigEl1vsEl2"), rawPionTracks[0].tpcNSigmaPi(), rawPionTracks[1].tpcNSigmaPi());
282+
283+
registry.fill(HIST("TwoPion/hP1"), onlyPionTracks[0].P(), rawPionTracks[0].tpcSignal());
284+
registry.fill(HIST("TwoPion/hP2"), onlyPionTracks[1].P(), rawPionTracks[1].tpcSignal());
285+
registry.fill(HIST("TwoPion/hTPCsig1"), rawPionTracks[0].tpcSignal(), rawPionTracks[1].tpcSignal());
286+
287+
registry.fill(HIST("TwoPion/Coherent/hMassUnlikeCoherent"), p.M());
288+
}
289+
// Incoherent Rho(0) selection
290+
if (p.Pt() > ptCoherent) {
291+
registry.fill(HIST("hSelectionCounter"), 10);
292+
registry.fill(HIST("TwoPion/Incoherent/hMassUnlikeInCoherent"), p.M());
293+
}
294+
}
295+
}
296+
297+
// Same charge particles
298+
if (rawPionTracks[0].sign() == rawPionTracks[1].sign()) {
299+
300+
registry.fill(HIST("hSelectionCounter"), 11);
301+
registry.fill(HIST("TwoPion/hMassLike"), p.M());
302+
303+
// Mass limit
304+
if ((p.M() > massMin) && (p.M() < massMax)) {
305+
306+
registry.fill(HIST("hSelectionCounter"), 12);
307+
registry.fill(HIST("TwoPion/hPtLike"), p.Pt());
308+
309+
// Coherent Rho(0) selection
310+
if (p.Pt() < ptCoherent) {
311+
312+
registry.fill(HIST("hSelectionCounter"), 13);
313+
registry.fill(HIST("TwoPion/Coherent/hMassLikeCoherent"), p.M());
314+
}
315+
// Incoherent Rho(0) selection
316+
if (p.Pt() > ptCoherent) {
317+
318+
registry.fill(HIST("hSelectionCounter"), 14);
319+
registry.fill(HIST("TwoPion/Incoherent/hMassLikeInCoherent"), p.M());
320+
}
321+
}
322+
}
323+
}
324+
}
325+
}
326+
}
327+
};
328+
329+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
330+
{
331+
return WorkflowSpec{
332+
adaptAnalysisTask<SGExclusiveJpsiMidrapidity>(cfgc)};
333+
}

0 commit comments

Comments
 (0)