Skip to content

Commit 60776c0

Browse files
authored
Enhance PID selection with rejection cuts
Added configurable rejection cuts for PID selection and updated histogram registration for PID validation.
1 parent eab4dea commit 60776c0

1 file changed

Lines changed: 128 additions & 0 deletions

File tree

PWGCF/EbyEFluctuations/Tasks/nchCumulantsId.cxx

Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ using namespace std;
4848
#define ID_BIT_EL 3
4949
#define ID_BIT_DE 4
5050

51+
#define MC_BIT_PI 0 // MC particle identification bits
52+
#define MC_BIT_KA 1
53+
#define MC_BIT_PR 2
54+
#define MC_BIT_EL 3
55+
#define MC_BIT_DE 4
56+
5157
#define BITSET(mask, ithBit) ((mask) |= (1 << (ithBit))) // avoid name bitset as std::bitset is already there
5258
#define BITCHECK(mask, ithBit) ((mask) & (1 << (ithBit))) // bit check will return int value, not bool, use BITCHECK != 0 in Analysi
5359

@@ -108,6 +114,7 @@ struct NchCumulantsId {
108114

109115
Configurable<bool> checkCollPosZMc{"checkCollPosZMc", false, "checkCollPosZMc"};
110116
Configurable<bool> flagUnusedVariableError{"flagUnusedVariableError", false, "flagUnusedVariableError"};
117+
Configurable<bool> cfgDoRejectionForId{"cfgDoRejectionForId", false, "Apply rejection cut before PID selection (selTrackForId)"};
111118

112119
Configurable<bool> cfgEvSel01doNoSameBunchPileup{"cfgEvSel01doNoSameBunchPileup", true, "apply kNoSameBunchPileup"};
113120
Configurable<bool> cfgEvSel02doIsGoodZvtxFT0vsPV{"cfgEvSel02doIsGoodZvtxFT0vsPV", true, "apply kIsGoodZvtxFT0vsPV"};
@@ -150,6 +157,12 @@ struct NchCumulantsId {
150157
Configurable<float> cfgIdPr08NSigmaTOFHighP{"cfgIdPr08NSigmaTOFHighP", 2.0, "cfgIdPr08NSigmaTOFHighP"};
151158
Configurable<float> cfgIdPr09NSigmaRadHighP{"cfgIdPr09NSigmaRadHighP", 4.0, "cfgIdPr09NSigmaRadHighP"};
152159

160+
Configurable<float> cfgIdElRejLowNSigma{"cfgIdElRejLowNSigma", -3.0, "cfgIdElRejLowNSigma"};
161+
Configurable<float> cfgIdElRejHighNSigma{"cfgIdElRejHighNSigma", 5.0, "cfgIdElRejHighNSigma"};
162+
Configurable<float> cfgIdPiRejNSigma{"cfgIdPiRejNSigma", 3.0, "cfgIdPiRejNSigma"};
163+
Configurable<float> cfgIdKaRejNSigma{"cfgIdKaRejNSigma", 3.0, "cfgIdKaRejNSigma"};
164+
Configurable<float> cfgIdPrRejNSigma{"cfgIdPrRejNSigma", 3.0, "cfgIdPrRejNSigma"};
165+
153166
struct : ConfigurableGroup {
154167
Configurable<float> cfgVetoId01PiTPC{"cfgVetoId01PiTPC", 3.0, "cfgVetoId01PiTPC"};
155168
Configurable<float> cfgVetoId02PiTOF{"cfgVetoId02PiTOF", 3.0, "cfgVetoId02PiTOF"};
@@ -244,8 +257,13 @@ struct NchCumulantsId {
244257
const AxisSpec axisPiCh(101, -1, 100, "Pion_Positive");
245258
const AxisSpec axisAPiCh(101, -1, 100, "Pion_Negative");
246259

260+
const AxisSpec axisIdTag = {32, -0.5f, 31.5f, "idTag"};
261+
const AxisSpec axisMcTag = {32, -0.5f, 31.5f, "mcTag"};
262+
247263
HistogramConfigSpec qnHist1({HistType::kTHnSparseD, {axisNch, axisPosCh, axisNegCh, axisPrCh, axisAPrCh, axisKaCh, axisAKaCh, axisNt, axisCent}});
248264
HistogramConfigSpec qnHist2({HistType::kTHnSparseD, {axisNch, axisPosCh, axisNegCh, axisPiCh, axisAPiCh, axisKaCh, axisAKaCh, axisNt, axisCent}});
265+
HistogramConfigSpec histTPCPIDSparse({HistType::kTHnSparseD, {axisP, axisTPCNSigma, axisIdTag, axisMcTag}});
266+
HistogramConfigSpec histTOFPIDSparse({HistType::kTHnSparseD, {axisP, axisTOFNSigma, axisIdTag, axisMcTag}});
249267

250268
HistogramConfigSpec histPPt({HistType::kTH2F, {axisP, axisPt}});
251269
HistogramConfigSpec histPTpcInnerParam({HistType::kTH2F, {axisP, axisTPCInnerParam}});
@@ -265,6 +283,17 @@ struct NchCumulantsId {
265283

266284
HistogramConfigSpec histPtMc({HistType::kTH1F, {axisPt}});
267285

286+
// Register histograms for PID validation
287+
// Register TPC spares per species
288+
hist.add("PIDValidation/tpcSparse_Pi", "p vs tpcNSigmaPi vs idTag vs mcTag (Pion)", histTPCPIDSparse);
289+
hist.add("PIDValidation/tpcSparse_Ka", "p vs tpcNSigmaKa vs idTag vs mcTag (Kaon)", histTPCPIDSparse);
290+
hist.add("PIDValidation/tpcSparse_Pr", "p vs tpcNSigmaPr vs idTag vs mcTag (Proton)", histTPCPIDSparse);
291+
292+
// Register TOF spares per species
293+
hist.add("PIDValidation/tofSparse_Pi", "p vs tofNSigmaPi vs idTag vs mcTag (Pion)", histTOFPIDSparse);
294+
hist.add("PIDValidation/tofSparse_Ka", "p vs tofNSigmaKa vs idTag vs mcTag (Kaon)", histTOFPIDSparse);
295+
hist.add("PIDValidation/tofSparse_Pr", "p vs tofNSigmaPr vs idTag vs mcTag (Proton)", histTOFPIDSparse);
296+
268297
// QA check histos
269298

270299
hist.add("QA/events/preSel/h_VtxZ", "V_{Z}", kTH1D, {axisVtxZ});
@@ -762,8 +791,44 @@ struct NchCumulantsId {
762791
}
763792
}
764793

794+
template <typename T>
795+
int getMCTag(const T& track)
796+
{
797+
int mcTag = 0;
798+
if (!track.has_mcParticle())
799+
return mcTag;
800+
auto mcPart = track.mcParticle();
801+
int pdgCode = std::abs(mcPart.pdgCode());
802+
803+
if (pdgCode == kPiPlus || pdgCode == kPiMinus)
804+
BITSET(mcTag, MC_BIT_PI);
805+
else if (pdgCode == kKPlus || pdgCode == kKMinus)
806+
BITSET(mcTag, MC_BIT_KA);
807+
else if (pdgCode == kProton || pdgCode == kProtonBar)
808+
BITSET(mcTag, MC_BIT_PR);
809+
else if (pdgCode == kElectron || pdgCode == kPositron)
810+
BITSET(mcTag, MC_BIT_EL);
811+
else if (pdgCode == kDeuteron || pdgCode == -kDeuteron)
812+
BITSET(mcTag, MC_BIT_DE);
813+
814+
return mcTag;
815+
}
765816
//
766817
//______________________________Identification Functions________________________________________________________________
818+
// Victor slection cuts for electron and other rejections
819+
template <typename T>
820+
bool selTrackForId(const T& track)
821+
{
822+
if (cfgIdElRejLowNSigma < track.tpcNSigmaEl() && track.tpcNSigmaEl() < cfgIdElRejHighNSigma &&
823+
std::fabs(track.tpcNSigmaPi()) > cfgIdPiRejNSigma &&
824+
std::fabs(track.tpcNSigmaKa()) > cfgIdKaRejNSigma &&
825+
std::fabs(track.tpcNSigmaPr()) > cfgIdPrRejNSigma) {
826+
return false;
827+
} else {
828+
return true;
829+
}
830+
}
831+
767832
// Pion
768833
template <typename T>
769834
bool selPion(const T& track, int& IdMethod)
@@ -1137,6 +1202,11 @@ struct NchCumulantsId {
11371202
nM += hPtEtaForEffCorrection[kCh][kNeg]->GetBinContent(ptEtaBin);
11381203
}
11391204

1205+
// Reject electrons first
1206+
if (cfgDoRejectionForId && !selTrackForId(track)) {
1207+
continue;
1208+
}
1209+
11401210
int idMethod;
11411211
// pion
11421212
if (selPion(track, idMethod)) {
@@ -1235,17 +1305,34 @@ struct NchCumulantsId {
12351305
idMethodKa = kUnidentified;
12361306
idMethodPr = kUnidentified;
12371307

1308+
// Get MC tag
1309+
int mcTag = getMCTag(track);
1310+
1311+
// Reject electrons first
1312+
if (cfgDoRejectionForId && !selTrackForId(track)) {
1313+
continue;
1314+
}
1315+
12381316
if (selPion(track, idMethodPi)) {
12391317
trackIsPion = true;
12401318
BITSET(trackIdTag, ID_BIT_PI);
1319+
hist.fill(HIST("PIDValidation/tpcSparse_Pi"), track.p(), track.tpcNSigmaPi(), trackIdTag, mcTag);
1320+
if (track.hasTOF())
1321+
hist.fill(HIST("PIDValidation/tofSparse_Pi"), track.p(), track.tofNSigmaPi(), trackIdTag, mcTag);
12411322
}
12421323
if (selKaon(track, idMethodKa)) {
12431324
trackIsKaon = true;
12441325
BITSET(trackIdTag, ID_BIT_KA);
1326+
hist.fill(HIST("PIDValidation/tpcSparse_Ka"), track.p(), track.tpcNSigmaKa(), trackIdTag, mcTag);
1327+
if (track.hasTOF())
1328+
hist.fill(HIST("PIDValidation/tofSparse_Ka"), track.p(), track.tofNSigmaKa(), trackIdTag, mcTag);
12451329
}
12461330
if (selProton(track, idMethodPr)) {
12471331
trackIsProton = true;
12481332
BITSET(trackIdTag, ID_BIT_PR);
1333+
hist.fill(HIST("PIDValidation/tpcSparse_Pr"), track.p(), track.tpcNSigmaPr(), trackIdTag, mcTag);
1334+
if (track.hasTOF())
1335+
hist.fill(HIST("PIDValidation/tofSparse_Pr"), track.p(), track.tofNSigmaPr(), trackIdTag, mcTag);
12491336
}
12501337

12511338
if constexpr (analysisType == doPurityProcessing) {
@@ -1555,6 +1642,8 @@ struct NchCumulantsId {
15551642
continue;
15561643
int pdg = mcPart.pdgCode();
15571644

1645+
int mcTag = getMCTag(track);
1646+
15581647
fillTrackQA<qaTracksPostSel>(track);
15591648

15601649
trackIsPion = false;
@@ -1565,17 +1654,41 @@ struct NchCumulantsId {
15651654
idMethodKa = kUnidentified;
15661655
idMethodPr = kUnidentified;
15671656

1657+
// Reject electrons first
1658+
if (cfgDoRejectionForId && !selTrackForId(track)) {
1659+
continue;
1660+
}
1661+
1662+
// Fill separate spares for each species if it passes the cut
15681663
if (selPion(track, idMethodPi)) {
15691664
trackIsPion = true;
15701665
BITSET(trackIdTag, ID_BIT_PI);
1666+
// Fill TPC sparse for pion
1667+
hist.fill(HIST("PIDValidation/tpcSparse_Pi"), track.p(), track.tpcNSigmaPi(), trackIdTag, mcTag);
1668+
// Fill TOF sparse for pion if has TOF
1669+
if (track.hasTOF()) {
1670+
hist.fill(HIST("PIDValidation/tofSparse_Pi"), track.p(), track.tofNSigmaPi(), trackIdTag, mcTag);
1671+
}
15711672
}
15721673
if (selKaon(track, idMethodKa)) {
15731674
trackIsKaon = true;
15741675
BITSET(trackIdTag, ID_BIT_KA);
1676+
// Fill TPC sparse for kaon
1677+
hist.fill(HIST("PIDValidation/tpcSparse_Ka"), track.p(), track.tpcNSigmaKa(), trackIdTag, mcTag);
1678+
// Fill TOF sparse for kaon if has TOF
1679+
if (track.hasTOF()) {
1680+
hist.fill(HIST("PIDValidation/tofSparse_Ka"), track.p(), track.tofNSigmaKa(), trackIdTag, mcTag);
1681+
}
15751682
}
15761683
if (selProton(track, idMethodPr)) {
15771684
trackIsProton = true;
15781685
BITSET(trackIdTag, ID_BIT_PR);
1686+
// Fill TPC sparse for proton
1687+
hist.fill(HIST("PIDValidation/tpcSparse_Pr"), track.p(), track.tpcNSigmaPr(), trackIdTag, mcTag);
1688+
// Fill TOF sparse for proton if has TOF
1689+
if (track.hasTOF()) {
1690+
hist.fill(HIST("PIDValidation/tofSparse_Pr"), track.p(), track.tofNSigmaPr(), trackIdTag, mcTag);
1691+
}
15791692
}
15801693

15811694
// bool isKnownCharged = (std::abs(pdg) == kPiPlus ||
@@ -1614,6 +1727,11 @@ struct NchCumulantsId {
16141727
nAPiRec += hPtEtaForEffCorrection[kPi][kNeg]->GetBinContent(ptEtaBin);
16151728
fillRecoTrackQA<recoAnalysisDir, kPi, kNeg>(recoAnalysis, track);
16161729
}
1730+
// PID band QA for pions
1731+
if (idMethodPi == kTPCidentified)
1732+
fillIdentificationQA<qaTracksIdfd, kPi, tpcId>(hist, track);
1733+
if (idMethodPi == kTPCTOFidentified)
1734+
fillIdentificationQA<qaTracksIdfd, kPi, tpctofId>(hist, track);
16171735
} else if (trackIsKaon) {
16181736
if (track.sign() > 0) {
16191737
nKaRec += hPtEtaForEffCorrection[kKa][kPos]->GetBinContent(ptEtaBin);
@@ -1622,6 +1740,11 @@ struct NchCumulantsId {
16221740
nAKaRec += hPtEtaForEffCorrection[kKa][kNeg]->GetBinContent(ptEtaBin);
16231741
fillRecoTrackQA<recoAnalysisDir, kKa, kNeg>(recoAnalysis, track);
16241742
}
1743+
// PID band QA for kaons
1744+
if (idMethodKa == kTPCidentified)
1745+
fillIdentificationQA<qaTracksIdfd, kKa, tpcId>(hist, track);
1746+
if (idMethodKa == kTPCTOFidentified)
1747+
fillIdentificationQA<qaTracksIdfd, kKa, tpctofId>(hist, track);
16251748
} else if (trackIsProton) {
16261749
if (track.sign() > 0) {
16271750
nPrRec += hPtEtaForEffCorrection[kPr][kPos]->GetBinContent(ptEtaBin);
@@ -1630,6 +1753,11 @@ struct NchCumulantsId {
16301753
nAPrRec += hPtEtaForEffCorrection[kPr][kNeg]->GetBinContent(ptEtaBin);
16311754
fillRecoTrackQA<recoAnalysisDir, kPr, kNeg>(recoAnalysis, track);
16321755
}
1756+
// PID band QA for protons
1757+
if (idMethodPr == kTPCidentified)
1758+
fillIdentificationQA<qaTracksIdfd, kPr, tpcId>(hist, track);
1759+
if (idMethodPr == kTPCTOFidentified)
1760+
fillIdentificationQA<qaTracksIdfd, kPr, tpctofId>(hist, track);
16331761
}
16341762
// purity check - check pdg aginst sign
16351763
bool purityPion = false;

0 commit comments

Comments
 (0)