Skip to content

Commit c9e57b7

Browse files
Preet-BhanjanPreet Patialibuild
authored
[PWGCF] Addition of nSigma PID function (#8838)
Co-authored-by: Preet Pati <preet@preet-2.local> Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 1a597d4 commit c9e57b7

File tree

2 files changed

+94
-59
lines changed

2 files changed

+94
-59
lines changed

PWGCF/Flow/Tasks/CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ o2physics_add_dpl_workflow(flow-gf
3939
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore
4040
COMPONENT_NAME Analysis)
4141

42-
o2physics_add_dpl_workflow(flow-pbpb-pikp-task
43-
SOURCES FlowPbPbpikp.cxx
42+
o2physics_add_dpl_workflow(flow-pbpb-pikp
43+
SOURCES flowPbpbPikp.cxx
4444
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore O2Physics::GFWCore
4545
COMPONENT_NAME Analysis)
4646

Lines changed: 92 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
/// \file flowPbpbPikp.cxx
13+
/// \brief PID flow using the generic framework
14+
/// \author Preet Bhanjan Pati <bhanjanpreet@gmail.com>
15+
1216
#include <CCDB/BasicCCDBManager.h>
1317
#include <cmath>
1418
#include <vector>
15-
#include <iostream>
1619
#include <utility>
1720
#include <array>
1821
#include <string>
@@ -48,13 +51,14 @@
4851
using namespace o2;
4952
using namespace o2::framework;
5053
using namespace o2::framework::expressions;
54+
using namespace std;
5155

5256
#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable<TYPE> NAME{#NAME, DEFAULT, HELP};
5357

54-
struct GfwPidflow {
58+
struct FlowPbpbPikp {
5559
Service<ccdb::BasicCCDBManager> ccdb;
56-
Configurable<int64_t> nolaterthan{"ccdb-no-later-than", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"};
57-
Configurable<std::string> url{"ccdb-url", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"};
60+
Configurable<int64_t> noLaterThan{"noLaterThan", std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count(), "latest acceptable timestamp of creation for the object"};
61+
Configurable<std::string> ccdbUrl{"ccdbUrl", "http://ccdb-test.cern.ch:8080", "url of the ccdb repository"};
5862

5963
O2_DEFINE_CONFIGURABLE(cfgCutVertex, float, 10.0f, "Accepted z-vertex range")
6064
O2_DEFINE_CONFIGURABLE(cfgCutPtPOIMin, float, 0.2f, "Minimal pT for poi tracks")
@@ -69,11 +73,11 @@ struct GfwPidflow {
6973
ConfigurableAxis axisVertex{"axisVertex", {20, -10, 10}, "vertex axis for histograms"};
7074
ConfigurableAxis axisPhi{"axisPhi", {60, 0.0, constants::math::TwoPI}, "phi axis for histograms"};
7175
ConfigurableAxis axisEta{"axisEta", {40, -1., 1.}, "eta axis for histograms"};
72-
ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.2, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.20, 1.40, 1.60, 1.80, 2.00, 2.20, 2.40, 2.60, 2.80, 3.00, 3.50, 4.00, 5.00, 6.00, 8.00, 10.00}, "pt axis for histograms"};
76+
ConfigurableAxis axisPt{"axisPt", {VARIABLE_WIDTH, 0.20, 0.30, 0.40, 0.50, 0.60, 0.70, 0.80, 0.90, 1.00, 1.20, 1.40, 1.60, 1.80, 2.00, 2.20, 2.40, 2.60, 2.80, 3.00, 3.50, 4.00, 5.00, 6.00, 8.00, 10.00}, "pt axis for histograms"};
7377
ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90}, "centrality axis for histograms"};
7478
ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {80, -5, 5}, "nsigmaTPC axis"};
7579
ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"};
76-
ConfigurableAxis axisparticles{"axisparticles", {3, 0, 3}, "axis for different hadrons"};
80+
ConfigurableAxis axisParticles{"axisParticles", {3, 0, 3}, "axis for different hadrons"};
7781

7882
Filter collisionFilter = nabs(aod::collision::posZ) < cfgCutVertex;
7983
Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtPOIMin) && (aod::track::pt < cfgCutPtPOIMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t) true)) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls);
@@ -86,14 +90,15 @@ struct GfwPidflow {
8690
TAxis* fPtAxis;
8791
TRandom3* fRndm = new TRandom3(0);
8892

89-
using aodCollisions = soa::Filtered<soa::Join<aod::Collisions, aod::EvSels, aod::FT0Mults, aod::MultZeqs, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs>>;
90-
using aodTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::pidBayes, aod::pidBayesPi, aod::pidBayesKa, aod::pidBayesPr, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>>;
93+
using AodCollisions = soa::Filtered<soa::Join<aod::Collisions, aod::EvSels, aod::FT0Mults, aod::MultZeqs, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs>>;
94+
// using AodTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::pidBayes, aod::pidBayesPi, aod::pidBayesKa, aod::pidBayesPr, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>>;
95+
using AodTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>>;
9196

9297
void init(InitContext const&)
9398
{
94-
ccdb->setURL(url.value);
99+
ccdb->setURL(ccdbUrl.value);
95100
ccdb->setCaching(true);
96-
ccdb->setCreatedNotAfter(nolaterthan.value);
101+
ccdb->setCreatedNotAfter(noLaterThan.value);
97102

98103
histos.add("hPhi", "", {HistType::kTH1D, {axisPhi}});
99104
histos.add("hEta", "", {HistType::kTH1D, {axisEta}});
@@ -106,28 +111,28 @@ struct GfwPidflow {
106111
histos.add("c22_gap08_ka", "", {HistType::kTProfile, {axisMultiplicity}});
107112
histos.add("c22_gap08_pr", "", {HistType::kTProfile, {axisMultiplicity}});
108113
histos.add("c24_full", "", {HistType::kTProfile, {axisMultiplicity}});
109-
histos.add("TofTpcNsigma", "", {HistType::kTHnSparseD, {{axisparticles, axisNsigmaTPC, axisNsigmaTOF}}});
110-
114+
histos.add("TofTpcNsigma", "", {HistType::kTHnSparseD, {{axisParticles, axisNsigmaTPC, axisNsigmaTOF, axisPt}}});
115+
histos.add("partCount", "", {HistType::kTHnSparseD, {{axisParticles, axisMultiplicity, axisPt}}});
111116
o2::framework::AxisSpec axis = axisPt;
112117
int nPtBins = axis.binEdges.size() - 1;
113-
double* PtBins = &(axis.binEdges)[0];
114-
fPtAxis = new TAxis(nPtBins, PtBins);
118+
double* ptBins = &(axis.binEdges)[0];
119+
fPtAxis = new TAxis(nPtBins, ptBins);
115120

116121
TObjArray* oba = new TObjArray();
117122
oba->Add(new TNamed("Ch08Gap22", "Ch08Gap22"));
118-
for (Int_t i = 0; i < fPtAxis->GetNbins(); i++)
123+
for (int i = 0; i < fPtAxis->GetNbins(); i++)
119124
oba->Add(new TNamed(Form("Ch08Gap22_pt_%i", i + 1), "Ch08Gap22_pTDiff"));
120125
oba->Add(new TNamed("Pi08Gap22", "Pi08Gap22"));
121-
for (Int_t i = 0; i < fPtAxis->GetNbins(); i++)
126+
for (int i = 0; i < fPtAxis->GetNbins(); i++)
122127
oba->Add(new TNamed(Form("Pi08Gap22_pt_%i", i + 1), "Pi08Gap22_pTDiff"));
123128
oba->Add(new TNamed("Ka08Gap22", "Ka08Gap22"));
124-
for (Int_t i = 0; i < fPtAxis->GetNbins(); i++)
129+
for (int i = 0; i < fPtAxis->GetNbins(); i++)
125130
oba->Add(new TNamed(Form("Ka08Gap22_pt_%i", i + 1), "Ka08Gap22_pTDiff"));
126131
oba->Add(new TNamed("Pr08Gap22", "Pr08Gap22"));
127-
for (Int_t i = 0; i < fPtAxis->GetNbins(); i++)
132+
for (int i = 0; i < fPtAxis->GetNbins(); i++)
128133
oba->Add(new TNamed(Form("Pr08Gap22_pt_%i", i + 1), "Pr08Gap22_pTDiff"));
129134
oba->Add(new TNamed("ChFull24", "ChFull24"));
130-
for (Int_t i = 0; i < fPtAxis->GetNbins(); i++)
135+
for (int i = 0; i < fPtAxis->GetNbins(); i++)
131136
oba->Add(new TNamed(Form("ChFull24_pt_%i", i + 1), "ChFull24_pTDiff"));
132137

133138
fFC->SetName("FlowContainer");
@@ -169,8 +174,36 @@ struct GfwPidflow {
169174
fGFW->CreateRegions();
170175
}
171176

177+
enum Particles {
178+
PIONS,
179+
KAONS,
180+
PROTONS
181+
};
182+
172183
template <typename TTrack>
173-
std::pair<int, int> GetBayesID(TTrack track)
184+
int getNsigmaPID(TTrack track)
185+
{
186+
// Computing Nsigma arrays for pion, kaon, and protons
187+
std::array<float, 3> nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()};
188+
std::array<float, 3> nSigmaCombined = {std::hypot(track.tpcNSigmaPi(), track.tofNSigmaPi()), std::hypot(track.tpcNSigmaKa(), track.tofNSigmaKa()), std::hypot(track.tpcNSigmaPr(), track.tofNSigmaPr())};
189+
int pid = -1;
190+
float nsigma = 3.0;
191+
192+
// Choose which nSigma to use
193+
std::array<float, 3> nSigmaToUse = (track.pt() > 0.4 && track.hasTOF()) ? nSigmaCombined : nSigmaTPC;
194+
195+
// Select particle with the lowest nsigma
196+
for (int i = 0; i < 3; ++i) {
197+
if (std::abs(nSigmaToUse[i]) < nsigma) {
198+
pid = i;
199+
nsigma = std::abs(nSigmaToUse[i]);
200+
}
201+
}
202+
return pid + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton
203+
}
204+
205+
/*template <typename TTrack>
206+
std::pair<int, int> getBayesID(TTrack track)
174207
{
175208
std::array<int, 3> bayesprobs = {static_cast<int>(track.bayesPi()), static_cast<int>(track.bayesKa()), static_cast<int>(track.bayesPr())};
176209
int bayesid = -1;
@@ -186,50 +219,50 @@ struct GfwPidflow {
186219
}
187220
188221
template <typename TTrack>
189-
int GetBayesPIDIndex(TTrack track)
222+
int getBayesPIDIndex(TTrack track)
190223
{
191224
int maxProb[3] = {80, 80, 80};
192225
int pidID = -1;
193-
std::pair<int, int> idprob = GetBayesID(track);
194-
if (idprob.first == 0 || idprob.first == 1 || idprob.first == 2) { // 0 = pion, 1 = kaon, 2 = proton
226+
std::pair<int, int> idprob = getBayesID(track);
227+
if (idprob.first == PIONS || idprob.first == KAONS || idprob.first == PROTONS) { // 0 = pion, 1 = kaon, 2 = proton
195228
pidID = idprob.first;
196229
float nsigmaTPC[3] = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()};
197230
if (idprob.second > maxProb[pidID]) {
198-
if (abs(nsigmaTPC[pidID]) > 3)
231+
if (std::fabs(nsigmaTPC[pidID]) > 3)
199232
return 0;
200233
return pidID + 1; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton
201234
} else {
202235
return 0;
203236
}
204237
}
205238
return 0;
206-
}
239+
}*/
207240

208241
template <char... chars>
209-
void FillProfile(const GFW::CorrConfig& corrconf, const ConstStr<chars...>& tarName, const double& cent)
242+
void fillProfile(const GFW::CorrConfig& corrconf, const ConstStr<chars...>& tarName, const double& cent)
210243
{
211244
double dnx, val;
212245
dnx = fGFW->Calculate(corrconf, 0, kTRUE).real();
213246
if (dnx == 0)
214247
return;
215248
if (!corrconf.pTDif) {
216249
val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx;
217-
if (TMath::Abs(val) < 1)
250+
if (std::fabs(val) < 1)
218251
histos.fill(tarName, cent, val, dnx);
219252
return;
220253
}
221-
for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) {
254+
for (int i = 1; i <= fPtAxis->GetNbins(); i++) {
222255
dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real();
223256
if (dnx == 0)
224257
continue;
225258
val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx;
226-
if (TMath::Abs(val) < 1)
259+
if (std::fabs(val) < 1)
227260
histos.fill(tarName, fPtAxis->GetBinCenter(i), val, dnx);
228261
}
229262
return;
230263
}
231264

232-
void FillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm)
265+
void fillFC(const GFW::CorrConfig& corrconf, const double& cent, const double& rndm)
233266
{
234267
double dnx, val;
235268
dnx = fGFW->Calculate(corrconf, 0, kTRUE).real();
@@ -238,84 +271,86 @@ struct GfwPidflow {
238271
}
239272
if (!corrconf.pTDif) {
240273
val = fGFW->Calculate(corrconf, 0, kFALSE).real() / dnx;
241-
if (TMath::Abs(val) < 1) {
274+
if (std::fabs(val) < 1) {
242275
fFC->FillProfile(corrconf.Head.c_str(), cent, val, dnx, rndm);
243276
}
244277
return;
245278
}
246-
for (Int_t i = 1; i <= fPtAxis->GetNbins(); i++) {
279+
for (int i = 1; i <= fPtAxis->GetNbins(); i++) {
247280
dnx = fGFW->Calculate(corrconf, i - 1, kTRUE).real();
248281
if (dnx == 0)
249282
continue;
250283
val = fGFW->Calculate(corrconf, i - 1, kFALSE).real() / dnx;
251-
if (TMath::Abs(val) < 1)
284+
if (std::fabs(val) < 1)
252285
fFC->FillProfile(Form("%s_pt_%i", corrconf.Head.c_str(), i), cent, val, dnx, rndm);
253286
}
254287
return;
255288
}
256289

257-
void process(aodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, aodTracks const& tracks)
290+
void process(AodCollisions::iterator const& collision, aod::BCsWithTimestamps const&, AodTracks const& tracks)
258291
{
259-
int Ntot = tracks.size();
260-
if (Ntot < 1)
292+
int nTot = tracks.size();
293+
if (nTot < 1)
261294
return;
262295
if (!collision.sel8())
263296
return;
264-
float l_Random = fRndm->Rndm();
297+
float lRandom = fRndm->Rndm();
265298

266299
float vtxz = collision.posZ();
267300
histos.fill(HIST("hVtxZ"), vtxz);
268-
histos.fill(HIST("hMult"), Ntot);
301+
histos.fill(HIST("hMult"), nTot);
269302
histos.fill(HIST("hCent"), collision.centFT0C());
270303
fGFW->Clear();
271304
const auto cent = collision.centFT0C();
272305
float weff = 1, wacc = 1;
273306
int pidIndex;
274-
for (auto& track : tracks) {
307+
for (auto const& track : tracks) {
275308
double pt = track.pt();
276309
histos.fill(HIST("hPhi"), track.phi());
277310
histos.fill(HIST("hEta"), track.eta());
278311
histos.fill(HIST("hPt"), pt);
279312

280-
histos.fill(HIST("TofTpcNsigma"), 0, track.tpcNSigmaPi(), track.tofNSigmaPi());
281-
histos.fill(HIST("TofTpcNsigma"), 1, track.tpcNSigmaKa(), track.tofNSigmaKa());
282-
histos.fill(HIST("TofTpcNsigma"), 2, track.tpcNSigmaPr(), track.tofNSigmaPr());
313+
histos.fill(HIST("TofTpcNsigma"), PIONS, track.tpcNSigmaPi(), track.tofNSigmaPi(), pt);
314+
histos.fill(HIST("TofTpcNsigma"), KAONS, track.tpcNSigmaKa(), track.tofNSigmaKa(), pt);
315+
histos.fill(HIST("TofTpcNsigma"), PROTONS, track.tpcNSigmaPr(), track.tofNSigmaPr(), pt);
283316

284-
bool WithinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range
285-
bool WithinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range
317+
bool withinPtPOI = (cfgCutPtPOIMin < pt) && (pt < cfgCutPtPOIMax); // within POI pT range
318+
bool withinPtRef = (cfgCutPtMin < pt) && (pt < cfgCutPtMax); // within RF pT range
286319

287-
pidIndex = GetBayesPIDIndex(track);
288-
if (WithinPtRef)
320+
// pidIndex = getBayesPIDIndex(track);
321+
pidIndex = getNsigmaPID(track);
322+
if (withinPtRef)
289323
fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 1);
290-
if (WithinPtPOI)
324+
if (withinPtPOI)
291325
fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 128);
292-
if (WithinPtPOI && WithinPtRef)
326+
if (withinPtPOI && withinPtRef)
293327
fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 256);
294328
fGFW->Fill(track.eta(), 1, track.phi(), wacc * weff, 512);
295329

296330
if (pidIndex) {
297-
if (WithinPtPOI)
331+
histos.fill(HIST("partCount"), pidIndex - 1, cent, pt);
332+
if (withinPtPOI)
298333
fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 1 << (pidIndex));
299-
if (WithinPtPOI && WithinPtRef)
334+
if (withinPtPOI && withinPtRef)
300335
fGFW->Fill(track.eta(), fPtAxis->FindBin(pt) - 1, track.phi(), wacc * weff, 1 << (pidIndex + 3));
301336
}
302337
}
303338

304339
// Filling c22 with ROOT TProfile
305-
FillProfile(corrconfigs.at(0), HIST("c22_gap08"), cent);
306-
FillProfile(corrconfigs.at(1), HIST("c22_gap08_pi"), cent);
307-
FillProfile(corrconfigs.at(2), HIST("c22_gap08_ka"), cent);
308-
FillProfile(corrconfigs.at(3), HIST("c22_gap08_pr"), cent);
309-
FillProfile(corrconfigs.at(4), HIST("c24_full"), cent);
340+
fillProfile(corrconfigs.at(0), HIST("c22_gap08"), cent);
341+
fillProfile(corrconfigs.at(1), HIST("c22_gap08_pi"), cent);
342+
fillProfile(corrconfigs.at(2), HIST("c22_gap08_ka"), cent);
343+
fillProfile(corrconfigs.at(3), HIST("c22_gap08_pr"), cent);
344+
fillProfile(corrconfigs.at(4), HIST("c24_full"), cent);
310345

311346
for (uint l_ind = 0; l_ind < corrconfigs.size(); l_ind++) {
312-
FillFC(corrconfigs.at(l_ind), cent, l_Random);
347+
fillFC(corrconfigs.at(l_ind), cent, lRandom);
313348
}
314349

315350
} // end of process
316351
};
317352

318353
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
319354
{
320-
return WorkflowSpec{adaptAnalysisTask<GfwPidflow>(cfgc)};
355+
return WorkflowSpec{adaptAnalysisTask<FlowPbpbPikp>(cfgc)};
321356
}

0 commit comments

Comments
 (0)