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;
6264using namespace o2 ::constants::math;
6365
6466auto static constexpr KminCharge = 3 .0f ;
67+ auto static constexpr KPidMaskPion = 2 ;
68+ auto static constexpr KPidMaskKaon = 4 ;
69+ auto static constexpr KPidMaskProton = 8 ;
6570
6671struct 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
10721213WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments