Skip to content

Commit 265bbd7

Browse files
authored
[PWGCF] Enhance PID QA and histogram configurations (#17384)
1 parent 900205e commit 265bbd7

1 file changed

Lines changed: 144 additions & 3 deletions

File tree

PWGCF/TwoParticleCorrelations/Tasks/longrangecorrDerived.cxx

Lines changed: 144 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
#include "Common/Core/TrackSelectionDefaults.h"
2626
#include "Common/DataModel/EventSelection.h"
2727
#include "Common/DataModel/McCollisionExtra.h"
28+
#include "Common/DataModel/PIDResponseTOF.h"
29+
#include "Common/DataModel/PIDResponseTPC.h"
2830
#include "Common/DataModel/TrackSelectionTables.h"
2931

3032
#include <CCDB/BasicCCDBManager.h>
@@ -62,6 +64,9 @@ using namespace o2::aod::evsel;
6264
using namespace o2::constants::math;
6365

6466
auto static constexpr KminCharge = 3.0f;
67+
auto static constexpr KPidMaskPion = 2;
68+
auto static constexpr KPidMaskKaon = 4;
69+
auto static constexpr KPidMaskProton = 8;
6570

6671
struct LongrangecorrDerived {
6772

@@ -105,14 +110,25 @@ struct LongrangecorrDerived {
105110
Configurable<bool> cfgRequireFt0aInnerRing{"cfgRequireFt0aInnerRing", false, "Consider FT0A Inner Ring"};
106111
Configurable<bool> cfgRequireFt0cOuterRing{"cfgRequireFt0cOuterRing", false, "Consider FT0C Outer Ring"};
107112
Configurable<bool> cfgRequireFt0cInnerRing{"cfgRequireFt0cInnerRing", false, "Consider FT0C Inner Ring"};
113+
114+
Configurable<float> cfgTofPidPtCut{"cfgTofPidPtCut", 0.4f, "Minimum pt to use TOF N-sigma"};
115+
Configurable<float> cfgPidNsigmaMax{"cfgPidNsigmaMax", 1.5f, "Maximum n-sigma for PID"};
116+
Configurable<float> cfgPidNsigmaMin{"cfgPidNsigmaMin", -1.5f, "Minimum n-sigma for PID"};
117+
Configurable<bool> cfgGetNsigmaQA{"cfgGetNsigmaQA", true, "Get QA histograms for PID selection"};
118+
Configurable<bool> cfgGetdEdx{"cfgGetdEdx", true, "Get dEdx histograms for TPC signal"};
119+
108120
} cfgSel;
109121

110122
struct : ConfigurableGroup {
111123
ConfigurableAxis axisMultQA{"axisMultQA", {500, -0.5, 499.5}, "multiplicity QA axis"};
112-
ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 10, 15, 25, 50, 60, 1000}, "multiplicity axis"};
124+
ConfigurableAxis axisMultiplicity{"axisMultiplicity", {VARIABLE_WIDTH, 0, 26, 46, 133, 1000}, "multiplicity axis"};
125+
ConfigurableAxis axisCentrality{"axisCentrality", {VARIABLE_WIDTH, 0, 5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100}, "Centrality (%)"};
126+
113127
ConfigurableAxis axisPhi{"axisPhi", {96, 0, TwoPI}, "#phi axis"};
114128
ConfigurableAxis axisEtaTrig{"axisEtaTrig", {40, -1., 1.}, "#eta trig axis"};
115129
ConfigurableAxis axisPtTrigger{"axisPtTrigger", {VARIABLE_WIDTH, 0.5, 1.0, 1.5, 2.0, 3.0, 4.0, 6.0, 10.0}, "pt trigger axis for histograms"};
130+
ConfigurableAxis axisPtQA{"axisPtQA", {50, 0.0, 8.0}, "pt axis for PID QA histograms"};
131+
116132
ConfigurableAxis axisVtxZ{"axisVtxZ", {40, -20, 20}, "vertex axis"};
117133
ConfigurableAxis axisEtaAssoc{"axisEtaAssoc", {96, 3.5, 4.9}, "#eta assoc axis"};
118134
ConfigurableAxis axisDeltaPhi{"axisDeltaPhi", {72, -PIHalf, PIHalf * 3}, "delta phi axis for histograms"};
@@ -138,6 +154,11 @@ struct LongrangecorrDerived {
138154
ConfigurableAxis axisVertexEfficiency{"axisVertexEfficiency", {10, -10, 10}, "vertex axis for efficiency histograms"};
139155
ConfigurableAxis axisEtaEfficiency{"axisEtaEfficiency", {20, -1.0, 1.0}, "eta axis for efficiency histograms"};
140156
ConfigurableAxis axisPtEfficiency{"axisPtEfficiency", {1, 0.5, 8.0}, "pt axis for efficiency histograms"};
157+
158+
ConfigurableAxis axisNsigmaTPC{"axisNsigmaTPC", {80, -5, 5}, "nsigmaTPC axis"};
159+
ConfigurableAxis axisNsigmaTOF{"axisNsigmaTOF", {80, -5, 5}, "nsigmaTOF axis"};
160+
ConfigurableAxis axisTpcSignal{"axisTpcSignal", {250, 0, 250}, "dEdx axis for TPC"};
161+
141162
} cfgAxis;
142163

143164
Configurable<float> cfgFv0Cut{"cfgFv0Cut", 50.0f, "FV0A threshold"};
@@ -265,6 +286,39 @@ struct LongrangecorrDerived {
265286
myTrackFilter.SetMaxChi2PerClusterTPC(cfgSel.cfgTpcMaxChi2PerCluster);
266287
myTrackFilter.SetMaxDcaZ(cfgSel.cfgTpcMaxDcaZ);
267288
myTrackFilter.print();
289+
290+
if (cfgSel.cfgGetNsigmaQA && (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton)) {
291+
292+
if (cfgSel.isUseCentEst) { // CENTRALITY MODE
293+
histos.add("TofTpcNsigma_before", "TPC vs TOF n#sigma Before Cuts;Centrality (%);p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}",
294+
kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF});
295+
296+
histos.add("TofTpcNsigma_after", "TPC vs TOF n#sigma After Cuts;Centrality (%);p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}",
297+
kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF});
298+
299+
if (cfgSel.cfgGetdEdx) {
300+
histos.add("TpcdEdx_ptwise", "TPC dE/dx Before Cuts;Centrality (%);p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}",
301+
kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF});
302+
303+
histos.add("TpcdEdx_ptwise_afterCut", "TPC dE/dx After Cuts;Centrality (%);p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}",
304+
kTHnSparseD, {cfgAxis.axisCentrality, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF});
305+
}
306+
} else { // MULTIPLICITY MODE
307+
histos.add("TofTpcNsigma_before", "TPC vs TOF n#sigma Before Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}",
308+
kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF});
309+
310+
histos.add("TofTpcNsigma_after", "TPC vs TOF n#sigma After Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);n#sigma_{TPC};n#sigma_{TOF}",
311+
kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisNsigmaTPC, cfgAxis.axisNsigmaTOF});
312+
313+
if (cfgSel.cfgGetdEdx) {
314+
histos.add("TpcdEdx_ptwise", "TPC dE/dx Before Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}",
315+
kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF});
316+
317+
histos.add("TpcdEdx_ptwise_afterCut", "TPC dE/dx After Cuts;Multiplicity (N_{ch});p_{T} (GeV/c);TPC dE/dx;n#sigma_{TOF}",
318+
kTHnSparseD, {cfgAxis.axisMultiplicity, cfgAxis.axisPtQA, cfgAxis.axisTpcSignal, cfgAxis.axisNsigmaTOF});
319+
}
320+
}
321+
}
268322
}
269323

270324
void loadEffCorrection(uint64_t timestamp)
@@ -277,15 +331,15 @@ struct LongrangecorrDerived {
277331
if (hTrkEff == nullptr) {
278332
LOGF(fatal, "Could not load efficiency histogram for trigger particles from %s", cfgSel.cfgEffccdbPath.value.c_str());
279333
}
280-
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgEffccdbPath.value.c_str(), (void*)hTrkEff);
334+
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgEffccdbPath.value.c_str(), static_cast<void*>(hTrkEff));
281335
}
282336

283337
if (cfgSel.cfgAccccdbPath.value.empty() == false) {
284338
hTrkAcc = ccdb->getForTimeStamp<TH3D>(cfgSel.cfgAccccdbPath, timestamp);
285339
if (hTrkAcc == nullptr) {
286340
LOGF(fatal, "Could not load NUA histogram for trigger particles from %s", cfgSel.cfgAccccdbPath.value.c_str());
287341
}
288-
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgAccccdbPath.value.c_str(), (void*)hTrkAcc);
342+
LOGF(info, "Loaded efficiency histogram from %s (%p)", cfgSel.cfgAccccdbPath.value.c_str(), static_cast<void*>(hTrkAcc));
289343
}
290344

291345
fLoadTrkEffCorr = true;
@@ -1020,6 +1074,92 @@ struct LongrangecorrDerived {
10201074
}
10211075
}
10221076

1077+
using CollStandardTable = soa::Join<aod::Collisions, aod::EvSels>;
1078+
using TrksStandardTable = soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFbeta, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr>;
1079+
1080+
void processPIDQA(CollsTable const& lrCollisions, TrksStandardTable const& standardTracks)
1081+
{
1082+
for (auto const& col : lrCollisions) {
1083+
1084+
if (std::abs(col.posZ()) >= cfgSel.cfgVtxCut) {
1085+
continue;
1086+
}
1087+
1088+
// EXTRACT CENTRALITY/MULTIPLICITY
1089+
float multiplicity = 1.0f;
1090+
if constexpr (requires { col.centrality(); }) {
1091+
if (cfgSel.isUseCentEst)
1092+
multiplicity = col.centrality();
1093+
else
1094+
multiplicity = col.multiplicity();
1095+
} else {
1096+
multiplicity = col.multiplicity();
1097+
}
1098+
1099+
auto tracks = standardTracks.sliceByCached(aod::track::collisionId, col.globalIndex(), this->cache);
1100+
1101+
for (auto const& track : tracks) {
1102+
if (!track.isGlobalTrack())
1103+
continue;
1104+
if (!myTrackFilter.IsSelected(track))
1105+
continue;
1106+
1107+
float tpcNsig = 0.0f, tofNsig = 0.0f;
1108+
if (cfgSel.cfgPidMask & KPidMaskPion) {
1109+
tpcNsig = track.tpcNSigmaPi();
1110+
tofNsig = track.tofNSigmaPi();
1111+
} else if (cfgSel.cfgPidMask & KPidMaskKaon) {
1112+
tpcNsig = track.tpcNSigmaKa();
1113+
tofNsig = track.tofNSigmaKa();
1114+
} else if (cfgSel.cfgPidMask & KPidMaskProton) {
1115+
tpcNsig = track.tpcNSigmaPr();
1116+
tofNsig = track.tofNSigmaPr();
1117+
}
1118+
1119+
// FILL BEFORE CUTS
1120+
if (cfgSel.cfgGetNsigmaQA && (cfgSel.cfgPidMask == KPidMaskPion || cfgSel.cfgPidMask == KPidMaskKaon || cfgSel.cfgPidMask == KPidMaskProton)) {
1121+
histos.fill(HIST("TofTpcNsigma_before"), multiplicity, track.pt(), tpcNsig, tofNsig);
1122+
if (cfgSel.cfgGetdEdx) {
1123+
histos.fill(HIST("TpcdEdx_ptwise"), multiplicity, track.pt(), track.tpcSignal(), tofNsig);
1124+
}
1125+
}
1126+
1127+
bool isTpcPion = (track.tpcNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPi() < cfgSel.cfgPidNsigmaMax);
1128+
bool isTpcKaon = (track.tpcNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaKa() < cfgSel.cfgPidNsigmaMax);
1129+
bool isTpcProton = (track.tpcNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tpcNSigmaPr() < cfgSel.cfgPidNsigmaMax);
1130+
1131+
bool isTofPion = (track.tofNSigmaPi() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPi() < cfgSel.cfgPidNsigmaMax);
1132+
bool isTofKaon = (track.tofNSigmaKa() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaKa() < cfgSel.cfgPidNsigmaMax);
1133+
bool isTofProton = (track.tofNSigmaPr() > cfgSel.cfgPidNsigmaMin && track.tofNSigmaPr() < cfgSel.cfgPidNsigmaMax);
1134+
1135+
bool isPion = false, isKaon = false, isProton = false;
1136+
if (track.pt() > cfgSel.cfgTofPidPtCut && track.hasTOF()) {
1137+
isPion = isTofPion && isTpcPion;
1138+
isKaon = isTofKaon && isTpcKaon;
1139+
isProton = isTofProton && isTpcProton;
1140+
} else if (!(track.pt() > cfgSel.cfgTofPidPtCut && !track.hasTOF())) {
1141+
isPion = isTpcPion;
1142+
isKaon = isTpcKaon;
1143+
isProton = isTpcProton;
1144+
}
1145+
1146+
if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) {
1147+
isPion = isKaon = isProton = false;
1148+
}
1149+
1150+
bool isTargetParticle = ((cfgSel.cfgPidMask & KPidMaskPion) && isPion) || ((cfgSel.cfgPidMask & KPidMaskKaon) && isKaon) || ((cfgSel.cfgPidMask & KPidMaskProton) && isProton);
1151+
1152+
// FILL AFTER CUTS
1153+
if (cfgSel.cfgGetNsigmaQA && isTargetParticle) {
1154+
histos.fill(HIST("TofTpcNsigma_after"), multiplicity, track.pt(), tpcNsig, tofNsig);
1155+
if (cfgSel.cfgGetdEdx) {
1156+
histos.fill(HIST("TpcdEdx_ptwise_afterCut"), multiplicity, track.pt(), track.tpcSignal(), tofNsig);
1157+
}
1158+
}
1159+
}
1160+
}
1161+
}
1162+
10231163
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aSE, "same event TPC vs FT0A", false);
10241164
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0aME, "mixed event TPC vs FT0A", false);
10251165
PROCESS_SWITCH(LongrangecorrDerived, processTpcft0cSE, "same event TPC vs FT0C", false);
@@ -1067,6 +1207,7 @@ struct LongrangecorrDerived {
10671207
PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cSE, "same MC gen event FT0A vs FT0C", false);
10681208
PROCESS_SWITCH(LongrangecorrDerived, processMcGenFt0aft0cME, "mixed MC gen event FT0A vs FT0C", false);
10691209
PROCESS_SWITCH(LongrangecorrDerived, processTPCtrackEff, "process TPC track efficiency", false);
1210+
PROCESS_SWITCH(LongrangecorrDerived, processPIDQA, "process PID QA on standard AODs", false);
10701211
};
10711212

10721213
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)

0 commit comments

Comments
 (0)