1414// / \author Zhiyong Lu (zhiyong.lu@cern.ch)
1515// / \since May/03/2025
1616
17- #include < CCDB/BasicCCDBManager.h>
18- #include " TRandom3.h"
19- #include " TF1.h"
20- #include < vector>
21- #include < string>
22-
23- #include " Framework/runDataProcessing.h"
24- #include " Framework/AnalysisTask.h"
25- #include " Framework/AnalysisDataModel.h"
26- #include " Framework/ASoAHelpers.h"
27- #include " Framework/StepTHn.h"
28- #include " Framework/HistogramRegistry.h"
29- #include " Framework/RunningWorkflowInfo.h"
30- #include " CommonConstants/MathConstants.h"
31- #include " Common/Core/RecoDecay.h"
32-
33- #include " Common/DataModel/EventSelection.h"
34- #include " Common/DataModel/Multiplicity.h"
35- #include " Common/DataModel/TrackSelectionTables.h"
36- #include " Common/DataModel/Centrality.h"
37- #include " PWGCF/DataModel/CorrelationsDerived.h"
38- #include " Common/DataModel/CollisionAssociationTables.h"
39- #include " Common/DataModel/PIDResponse.h"
4017#include " PWGCF/Core/CorrelationContainer.h"
4118#include " PWGCF/Core/PairCuts.h"
42- #include " PWGCF/GenericFramework/Core/GFWPowerArray .h"
19+ #include " PWGCF/DataModel/CorrelationsDerived .h"
4320#include " PWGCF/GenericFramework/Core/GFW.h"
4421#include " PWGCF/GenericFramework/Core/GFWCumulant.h"
22+ #include " PWGCF/GenericFramework/Core/GFWPowerArray.h"
4523#include " PWGCF/GenericFramework/Core/GFWWeights.h"
46- #include " DataFormatsParameters/GRPObject.h"
24+
25+ #include " Common/Core/RecoDecay.h"
26+ #include " Common/DataModel/Centrality.h"
27+ #include " Common/DataModel/CollisionAssociationTables.h"
28+ #include " Common/DataModel/EventSelection.h"
29+ #include " Common/DataModel/Multiplicity.h"
30+ #include " Common/DataModel/PIDResponse.h"
31+ #include " Common/DataModel/PIDResponseITS.h"
32+ #include " Common/DataModel/TrackSelectionTables.h"
33+
34+ #include " CommonConstants/MathConstants.h"
4735#include " DataFormatsParameters/GRPMagField.h"
36+ #include " DataFormatsParameters/GRPObject.h"
37+ #include " Framework/ASoAHelpers.h"
38+ #include " Framework/AnalysisDataModel.h"
39+ #include " Framework/AnalysisTask.h"
40+ #include " Framework/HistogramRegistry.h"
41+ #include " Framework/RunningWorkflowInfo.h"
42+ #include " Framework/StepTHn.h"
43+ #include " Framework/runDataProcessing.h"
44+ #include " ReconstructionDataFormats/PID.h"
45+ #include " ReconstructionDataFormats/Track.h"
46+ #include < CCDB/BasicCCDBManager.h>
47+
48+ #include " TF1.h"
49+ #include " TRandom3.h"
4850#include < TPDGCode.h>
4951
52+ #include < string>
53+ #include < vector>
54+
5055using namespace o2 ;
5156using namespace o2 ::framework;
5257using namespace o2 ::framework::expressions;
@@ -98,6 +103,9 @@ struct DiHadronCor {
98103 O2_DEFINE_CONFIGURABLE (cfgUseEventWeights, bool , false , " Use event weights for mixed event" )
99104 O2_DEFINE_CONFIGURABLE (cfgUsePtOrder, bool , true , " enable trigger pT < associated pT cut" )
100105 O2_DEFINE_CONFIGURABLE (cfgUsePtOrderInMixEvent, bool , true , " enable trigger pT < associated pT cut in mixed event" )
106+ O2_DEFINE_CONFIGURABLE (cfgPIDUseITSPID, bool , true , " Use ITS PID for particle identification" )
107+ O2_DEFINE_CONFIGURABLE (cfgPIDTofPtCut, float , 0 .5f , " Minimum pt to use TOF N-sigma" )
108+ O2_DEFINE_CONFIGURABLE (cfgPIDParticle, int , 0 , " 1 = pion, 2 = kaon, 3 = proton, 0 for no PID" )
101109
102110 SliceCache cache;
103111
@@ -112,6 +120,9 @@ struct DiHadronCor {
112120 ConfigurableAxis axisVtxMix{" axisVtxMix" , {VARIABLE_WIDTH, -10 , -9 , -8 , -7 , -6 , -5 , -4 , -3 , -2 , -1 , 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 }, " vertex axis for mixed event histograms" };
113121 ConfigurableAxis axisMultMix{" axisMultMix" , {VARIABLE_WIDTH, 0 , 10 , 20 , 40 , 60 , 80 , 100 , 120 , 140 , 160 , 180 , 200 , 220 , 240 , 260 }, " multiplicity / centrality axis for mixed event histograms" };
114122 ConfigurableAxis axisSample{" axisSample" , {cfgSampleSize, 0 , cfgSampleSize}, " sample axis for histograms" };
123+ Configurable<std::vector<double >> pidTofNsigmaCut{" pidTofNsigmaCut" , std::vector<double >{1.5 , 1.5 , 1.5 , -1.5 , -1.5 , -1.5 }, " TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma" };
124+ Configurable<std::vector<double >> pidItsNsigmaCut{" pidItsNsigmaCut" , std::vector<double >{3 , 3 , 3 , -3 , -3 , -3 }, " ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma" };
125+ Configurable<std::vector<double >> pidTpcNsigmaCut{" pidTpcNsigmaCut" , std::vector<double >{10 , 10 , 10 , -10 , -10 , -10 }, " TOF n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma" };
115126
116127 ConfigurableAxis axisVertexEfficiency{" axisVertexEfficiency" , {10 , -10 , 10 }, " vertex axis for efficiency histograms" };
117128 ConfigurableAxis axisEtaEfficiency{" axisEtaEfficiency" , {20 , -1.0 , 1.0 }, " eta axis for efficiency histograms" };
@@ -121,7 +132,7 @@ struct DiHadronCor {
121132 Filter collisionFilter = (nabs(aod::collision::posZ) < cfgCutVtxZ);
122133 Filter trackFilter = (nabs(aod::track::eta) < cfgCutEta) && (aod::track::pt > cfgCutPtMin) && (aod::track::pt < cfgCutPtMax) && ((requireGlobalTrackInFilter()) || (aod::track::isGlobalTrackSDD == (uint8_t ) true )) && (aod::track::tpcChi2NCl < cfgCutChi2prTPCcls) && (nabs(aod::track::dcaZ) < cfgCutDCAz);
123134 using FilteredCollisions = soa::Filtered<soa::Join<aod::Collisions, aod::EvSel, aod::CentFT0Cs, aod::CentFT0CVariant1s, aod::CentFT0Ms, aod::CentFV0As, aod::Mults>>;
124- using FilteredTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA>>;
135+ 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 >>;
125136 using FilteredTracksWithMCLabels = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA, aod::McTrackLabels>>;
126137
127138 // Filter for MCParticle
@@ -160,6 +171,15 @@ struct DiHadronCor {
160171 SameEvent = 1 ,
161172 MixedEvent = 3
162173 };
174+ std::vector<double > tofNsigmaCut;
175+ std::vector<double > itsNsigmaCut;
176+ std::vector<double > tpcNsigmaCut;
177+ o2::aod::ITSResponse itsResponse;
178+ enum Particles {
179+ PIONS,
180+ KAONS,
181+ PROTONS
182+ };
163183
164184 // persistent caches
165185 std::vector<float > efficiencyAssociatedCache;
@@ -290,6 +310,10 @@ struct DiHadronCor {
290310 same.setObject (new CorrelationContainer (" sameEvent" , " sameEvent" , corrAxis, effAxis, userAxis));
291311 mixed.setObject (new CorrelationContainer (" mixedEvent" , " mixedEvent" , corrAxis, effAxis, userAxis));
292312
313+ tofNsigmaCut = pidTofNsigmaCut;
314+ itsNsigmaCut = pidItsNsigmaCut;
315+ tpcNsigmaCut = pidTpcNsigmaCut;
316+
293317 LOGF (info, " End of init" );
294318 }
295319
@@ -334,6 +358,9 @@ struct DiHadronCor {
334358 template <typename TTrack>
335359 bool trackSelected (TTrack track)
336360 {
361+ if (cfgPIDParticle && getNsigmaPID (track) != cfgPIDParticle) {
362+ return false ;
363+ }
337364 return ((track.tpcNClsFound () >= cfgCutTPCclu) && (track.tpcNClsCrossedRows () >= cfgCutTPCCrossedRows) && (track.itsNCls () >= cfgCutITSclu));
338365 }
339366
@@ -962,6 +989,56 @@ struct DiHadronCor {
962989 }
963990 }
964991 PROCESS_SWITCH (DiHadronCor, processOntheflyMixed, " Process on-the-fly mixed events" , false );
992+
993+ template <typename TTrack>
994+ int getNsigmaPID (TTrack track)
995+ {
996+ // Computing Nsigma arrays for pion, kaon, and protons
997+ std::array<float , 3 > nSigmaTPC = {track.tpcNSigmaPi (), track.tpcNSigmaKa (), track.tpcNSigmaPr ()};
998+ std::array<float , 3 > nSigmaTOF = {track.tofNSigmaPi (), track.tofNSigmaKa (), track.tofNSigmaPr ()};
999+ 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)};
1000+ int pid = -1 ;
1001+
1002+ std::array<float , 3 > nSigmaToUse = cfgPIDUseITSPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS
1003+ std::vector<double > detectorNsigmaCut = cfgPIDUseITSPID ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS
1004+
1005+ bool isPion, isKaon, isProton;
1006+ bool isDetectedPion = nSigmaToUse[0 ] < detectorNsigmaCut[0 ] && nSigmaToUse[0 ] > detectorNsigmaCut[0 + 3 ];
1007+ bool isDetectedKaon = nSigmaToUse[1 ] < detectorNsigmaCut[1 ] && nSigmaToUse[1 ] > detectorNsigmaCut[1 + 3 ];
1008+ bool isDetectedProton = nSigmaToUse[2 ] < detectorNsigmaCut[2 ] && nSigmaToUse[2 ] > detectorNsigmaCut[2 + 3 ];
1009+
1010+ bool isTofPion = nSigmaTOF[0 ] < tofNsigmaCut[0 ] && nSigmaTOF[0 ] > tofNsigmaCut[0 + 3 ];
1011+ bool isTofKaon = nSigmaTOF[1 ] < tofNsigmaCut[1 ] && nSigmaTOF[1 ] > tofNsigmaCut[1 + 3 ];
1012+ bool isTofProton = nSigmaTOF[2 ] < tofNsigmaCut[2 ] && nSigmaTOF[2 ] > tofNsigmaCut[2 + 3 ];
1013+
1014+ if (track.pt () > cfgPIDTofPtCut && !track.hasTOF ()) {
1015+ return 0 ;
1016+ } else if (track.pt () > cfgPIDTofPtCut && track.hasTOF ()) {
1017+ isPion = isTofPion && isDetectedPion;
1018+ isKaon = isTofKaon && isDetectedKaon;
1019+ isProton = isTofProton && isDetectedProton;
1020+ } else {
1021+ isPion = isDetectedPion;
1022+ isKaon = isDetectedKaon;
1023+ isProton = isDetectedProton;
1024+ }
1025+
1026+ if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) {
1027+ return 0 ; // more than one particle satisfy the criteria
1028+ }
1029+
1030+ if (isPion) {
1031+ pid = PIONS;
1032+ } else if (isKaon) {
1033+ pid = KAONS;
1034+ } else if (isProton) {
1035+ pid = PROTONS;
1036+ } else {
1037+ return 0 ; // no particle satisfies the criteria
1038+ }
1039+
1040+ return pid + 1 ; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton
1041+ }
9651042};
9661043
9671044WorkflowSpec defineDataProcessing (ConfigContext const & cfgc)
0 commit comments