Skip to content

Commit 699ff3e

Browse files
committed
add PID selection
1 parent 5f48d15 commit 699ff3e

File tree

1 file changed

+114
-1
lines changed

1 file changed

+114
-1
lines changed

PWGCF/TwoParticleCorrelations/Tasks/longRangeDihadronCor.cxx

Lines changed: 114 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "Common/DataModel/FT0Corrected.h"
3030
#include "Common/DataModel/Multiplicity.h"
3131
#include "Common/DataModel/PIDResponse.h"
32+
#include "Common/DataModel/PIDResponseITS.h"
3233
#include "Common/DataModel/TrackSelectionTables.h"
3334

3435
#include "CommonConstants/MathConstants.h"
@@ -44,6 +45,8 @@
4445
#include "Framework/RunningWorkflowInfo.h"
4546
#include "Framework/StepTHn.h"
4647
#include "Framework/runDataProcessing.h"
48+
#include "ReconstructionDataFormats/PID.h"
49+
#include "ReconstructionDataFormats/Track.h"
4750
#include <CCDB/BasicCCDBManager.h>
4851

4952
#include "TF1.h"
@@ -59,9 +62,12 @@ using namespace o2::framework::expressions;
5962

6063
// define the filtered collisions and tracks
6164
#define O2_DEFINE_CONFIGURABLE(NAME, TYPE, DEFAULT, HELP) Configurable<TYPE> NAME{#NAME, DEFAULT, HELP};
65+
// template for labelled array
66+
static constexpr float LongArrayFloat[3][20] = {{1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {2.1, 2.2, 2.3, -2.1, -2.2, -2.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}, {3.1, 3.2, 3.3, -3.1, -3.2, -3.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2, 1.3, -1.1, -1.2, -1.3, 1.1, 1.2}};
6267

6368
struct LongRangeDihadronCor {
6469
Service<ccdb::BasicCCDBManager> ccdb;
70+
o2::aod::ITSResponse itsResponse;
6571

6672
O2_DEFINE_CONFIGURABLE(cfgCutVtxZ, float, 10.0f, "Accepted z-vertex range")
6773
O2_DEFINE_CONFIGURABLE(cfgCutPtMin, float, 0.2f, "minimum accepted track pT")
@@ -130,6 +136,12 @@ struct LongRangeDihadronCor {
130136
TF1* fT0AV0AMean = nullptr;
131137
TF1* fT0AV0ASigma = nullptr;
132138
} cfgFuncParas;
139+
struct : ConfigurableGroup {
140+
O2_DEFINE_CONFIGURABLE(cfgUseItsPID, bool, true, "Use ITS PID for particle identification")
141+
O2_DEFINE_CONFIGURABLE(cfgPIDParticle, int, 0, "1 = pion, 2 = kaon, 3 = proton, 4 = kshort, 5 = lambda, 6 = phi, 0 for no PID")
142+
O2_DEFINE_CONFIGURABLE(cfgTofPtCut, float, 0.5f, "Minimum pt to use TOF N-sigma")
143+
Configurable<LabeledArray<float>> nSigmas{"nSigmas", {LongArrayFloat[0], 3, 6, {"TPC", "TOF", "ITS"}, {"pos_pi", "pos_ka", "pos_pr", "neg_pi", "neg_ka", "neg_pr"}}, "Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative)"};
144+
} cfgPIDConfig;
133145

134146
SliceCache cache;
135147

@@ -161,7 +173,7 @@ struct LongRangeDihadronCor {
161173
Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ);
162174
Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == static_cast<uint8_t>(true))) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz);
163175
using FilteredCollisions = soa::Filtered<soa::Join<aod::Collisions, aod::EvSel, aod::CentFT0Cs, aod::CentFT0CVariant1s, aod::CentFT0Ms, aod::CentFV0As, aod::Mults>>;
164-
using FilteredTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA>>;
176+
using FilteredTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFbeta, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>>;
165177

166178
// FT0 geometry
167179
o2::ft0::Geometry ft0Det;
@@ -201,6 +213,31 @@ struct LongRangeDihadronCor {
201213
kFT0A = 0,
202214
kFT0C = 1
203215
};
216+
enum ParticleNsigma {
217+
kPionUp = 0,
218+
kKaonUp,
219+
kProtonUp,
220+
kPionLow,
221+
kKaonLow,
222+
kProtonLow
223+
};
224+
enum PIDIndex {
225+
kCharged = 0,
226+
kPions,
227+
kKaons,
228+
kProtons,
229+
kK0,
230+
kLambda,
231+
kPhi
232+
};
233+
enum DetectorType {
234+
kTPC = 0,
235+
kTOF,
236+
kITS
237+
};
238+
std::array<float, 6> tofNsigmaCut;
239+
std::array<float, 6> itsNsigmaCut;
240+
std::array<float, 6> tpcNsigmaCut;
204241

205242
void init(InitContext&)
206243
{
@@ -218,6 +255,28 @@ struct LongRangeDihadronCor {
218255

219256
LOGF(info, "Starting init");
220257

258+
// filling tpc nSigmas array
259+
tpcNsigmaCut[kPionUp] = cfgPIDConfig.nSigmas->getData()[kTPC][kPionUp];
260+
tpcNsigmaCut[kKaonUp] = cfgPIDConfig.nSigmas->getData()[kTPC][kKaonUp];
261+
tpcNsigmaCut[kProtonUp] = cfgPIDConfig.nSigmas->getData()[kTPC][kProtonUp];
262+
tpcNsigmaCut[kPionLow] = cfgPIDConfig.nSigmas->getData()[kTPC][kPionLow];
263+
tpcNsigmaCut[kKaonLow] = cfgPIDConfig.nSigmas->getData()[kTPC][kKaonLow];
264+
tpcNsigmaCut[kProtonLow] = cfgPIDConfig.nSigmas->getData()[kTPC][kProtonLow];
265+
// filling tof nSigmas array
266+
tofNsigmaCut[kPionUp] = cfgPIDConfig.nSigmas->getData()[kTOF][kPionUp];
267+
tofNsigmaCut[kKaonUp] = cfgPIDConfig.nSigmas->getData()[kTOF][kKaonUp];
268+
tofNsigmaCut[kProtonUp] = cfgPIDConfig.nSigmas->getData()[kTOF][kProtonUp];
269+
tofNsigmaCut[kPionLow] = cfgPIDConfig.nSigmas->getData()[kTOF][kPionLow];
270+
tofNsigmaCut[kKaonLow] = cfgPIDConfig.nSigmas->getData()[kTOF][kKaonLow];
271+
tofNsigmaCut[kProtonLow] = cfgPIDConfig.nSigmas->getData()[kTOF][kProtonLow];
272+
// filling its nSigmas array
273+
itsNsigmaCut[kPionUp] = cfgPIDConfig.nSigmas->getData()[kITS][kPionUp];
274+
itsNsigmaCut[kKaonUp] = cfgPIDConfig.nSigmas->getData()[kITS][kKaonUp];
275+
itsNsigmaCut[kProtonUp] = cfgPIDConfig.nSigmas->getData()[kITS][kProtonUp];
276+
itsNsigmaCut[kPionLow] = cfgPIDConfig.nSigmas->getData()[kITS][kPionLow];
277+
itsNsigmaCut[kKaonLow] = cfgPIDConfig.nSigmas->getData()[kITS][kKaonLow];
278+
itsNsigmaCut[kProtonLow] = cfgPIDConfig.nSigmas->getData()[kITS][kProtonLow];
279+
221280
// Event Counter
222281
if ((doprocessSameTpcFt0a || doprocessSameTpcFt0c || doprocessSameFt0aFt0c) && cfgUseAdditionalEventCut) {
223282
registry.add("hEventCountSpecific", "Number of Event;; Count", {HistType::kTH1D, {{12, 0, 12}}});
@@ -410,6 +469,58 @@ struct LongRangeDihadronCor {
410469
return ((track.tpcNClsFound() >= cfgCutTPCclu) && (track.tpcNClsCrossedRows() >= cfgCutTPCCrossedRows) && (track.itsNCls() >= cfgCutITSclu));
411470
}
412471

472+
template <typename TTrack>
473+
int getNsigmaPID(TTrack track)
474+
{
475+
// Computing Nsigma arrays for pion, kaon, and protons
476+
std::array<float, 3> nSigmaTPC = {track.tpcNSigmaPi(), track.tpcNSigmaKa(), track.tpcNSigmaPr()};
477+
std::array<float, 3> nSigmaTOF = {track.tofNSigmaPi(), track.tofNSigmaKa(), track.tofNSigmaPr()};
478+
std::array<float, 3> nSigmaITS = {itsResponse.nSigmaITS<o2::track::PID::Pion>(track), itsResponse.nSigmaITS<o2::track::PID::Kaon>(track), itsResponse.nSigmaITS<o2::track::PID::Proton>(track)};
479+
int pid = -1; // -1 = not identified, 1 = pion, 2 = kaon, 3 = proton
480+
481+
std::array<float, 3> nSigmaToUse = cfgPIDConfig.cfgUseItsPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS
482+
std::array<float, 6> detectorNsigmaCut = cfgPIDConfig.cfgUseItsPID ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS
483+
484+
bool isPion = false;
485+
bool isKaon = false;
486+
bool isProton = false;
487+
bool isDetectedPion = nSigmaToUse[kPionUp] < detectorNsigmaCut[kPionUp] && nSigmaToUse[kPionUp] > detectorNsigmaCut[kPionLow];
488+
bool isDetectedKaon = nSigmaToUse[kKaonUp] < detectorNsigmaCut[kKaonUp] && nSigmaToUse[kKaonUp] > detectorNsigmaCut[kKaonLow];
489+
bool isDetectedProton = nSigmaToUse[kProtonUp] < detectorNsigmaCut[kProtonUp] && nSigmaToUse[kProtonUp] > detectorNsigmaCut[kProtonLow];
490+
491+
bool isTofPion = nSigmaTOF[kPionUp] < tofNsigmaCut[kPionUp] && nSigmaTOF[kPionUp] > tofNsigmaCut[kPionLow];
492+
bool isTofKaon = nSigmaTOF[kKaonUp] < tofNsigmaCut[kKaonUp] && nSigmaTOF[kKaonUp] > tofNsigmaCut[kKaonLow];
493+
bool isTofProton = nSigmaTOF[kProtonUp] < tofNsigmaCut[kProtonUp] && nSigmaTOF[kProtonUp] > tofNsigmaCut[kProtonLow];
494+
495+
if (track.pt() > cfgPIDConfig.cfgTofPtCut && !track.hasTOF()) {
496+
return -1;
497+
} else if (track.pt() > cfgPIDConfig.cfgTofPtCut && track.hasTOF()) {
498+
isPion = isTofPion && isDetectedPion;
499+
isKaon = isTofKaon && isDetectedKaon;
500+
isProton = isTofProton && isDetectedProton;
501+
} else {
502+
isPion = isDetectedPion;
503+
isKaon = isDetectedKaon;
504+
isProton = isDetectedProton;
505+
}
506+
507+
if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) {
508+
return -1; // more than one particle satisfy the criteria
509+
}
510+
511+
if (isPion) {
512+
pid = kPions;
513+
} else if (isKaon) {
514+
pid = kKaons;
515+
} else if (isProton) {
516+
pid = kProtons;
517+
} else {
518+
return -1; // no particle satisfies the criteria
519+
}
520+
521+
return pid; // -1 = not identified, 1 = pion, 2 = kaon, 3 = proton
522+
}
523+
413524
void loadAlignParam(uint64_t timestamp)
414525
{
415526
offsetFT0 = ccdb->getForTimeStamp<std::vector<o2::detectors::AlignParam>>("FT0/Calib/Align", timestamp);
@@ -558,6 +669,8 @@ struct LongRangeDihadronCor {
558669

559670
if (!trackSelected(track1))
560671
continue;
672+
if (cfgPIDConfig.cfgPIDParticle && getNsigmaPID(track1) != cfgPIDConfig.cfgPIDParticle)
673+
continue; // if PID is selected, check if the track has the right PID
561674
if (!getEfficiencyCorrection(triggerWeight, track1.eta(), track1.pt(), posZ))
562675
continue;
563676
if (system == SameEvent) {

0 commit comments

Comments
 (0)