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 " CCDB/BasicCCDBManager.h"
4546#include " Framework/O2DatabasePDGPlugin.h"
4647#include " Framework/StepTHn.h"
4748#include " Framework/runDataProcessing.h"
49+ #include " ReconstructionDataFormats/PID.h"
4850#include " ReconstructionDataFormats/Track.h"
4951
5052#include < TComplex.h>
@@ -90,6 +92,12 @@ enum KindOfCorrType {
9092 kFT0AFT0C
9193};
9294
95+ enum KindOfParticles {
96+ PIONS,
97+ KAONS,
98+ PROTONS
99+ };
100+
93101static constexpr std::string_view kCorrType [] = {" Ft0aGlobal/" , " Ft0cGlobal/" , " MftGlobal/" , " Ft0aMft/" , " Ft0aFt0c/" };
94102static constexpr std::string_view kEvntType [] = {" SE/" , " ME/" };
95103auto static constexpr kMinFt0cCell = 96 ;
@@ -138,6 +146,12 @@ struct LongrangeCorrelation {
138146 Configurable<bool > isApplyGoodZvtxFT0vsPV{" isApplyGoodZvtxFT0vsPV" , false , " Enable GoodZvtxFT0vsPV cut" };
139147 Configurable<bool > isReadoutCenter{" isReadoutCenter" , false , " Enable Readout Center" };
140148 Configurable<bool > isUseEffCorr{" isUseEffCorr" , false , " Enable efficiency correction" };
149+ Configurable<bool > isUseItsPid{" isUseItsPid" , false , " Use ITS PID for particle identification" };
150+ Configurable<float > cfgTofPidPtCut{" cfgTofPidPtCut" , 0 .3f , " Minimum pt to use TOF N-sigma" };
151+ Configurable<int > cfgTrackPid{" cfgTrackPid" , 0 , " 1 = pion, 2 = kaon, 3 = proton, 0 for no PID" };
152+ Configurable<std::vector<double >> itsNsigmaPidCut{" itsNsigmaPidCut" , std::vector<double >{3 , 2.5 , 2 , -3 , -2.5 , -2 }, " ITS n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma" };
153+ Configurable<std::vector<double >> tpcNsigmaPidCut{" tpcNsigmaPidCut" , std::vector<double >{1.5 , 1.5 , 1.5 , -1.5 , -1.5 , -1.5 }, " TPC n-sigma cut for pions_posNsigma, kaons_posNsigma, protons_posNsigma, pions_negNsigma, kaons_negNsigma, protons_negNsigma" };
154+ Configurable<std::vector<double >> tofNsigmaPidCut{" tofNsigmaPidCut" , 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" };
141155 Configurable<std::string> cfgEffccdbPath{" cfgEffccdbPath" , " /alice/data/CCDB/Users/a/abmodak/OO/Efficiency" , " Browse track eff object from CCDB" };
142156 Configurable<std::string> cfgMultccdbPath{" cfgMultccdbPath" , " /alice/data/CCDB/Users/a/abmodak/OO/Multiplicity" , " Browse mult efficiency object from CCDB" };
143157 ConfigurableAxis axisDeltaPhi{" axisDeltaPhi" , {72 , -PIHalf, PIHalf * 3 }, " delta phi axis for histograms" };
@@ -159,7 +173,7 @@ struct LongrangeCorrelation {
159173 ConfigurableAxis channelFt0aAxis{" channelFt0aAxis" , {96 , 0.0 , 96.0 }, " FT0A channel" };
160174
161175 using CollTable = soa::Join<aod::Collisions, aod::EvSels, aod::LRMultTables>;
162- using TrksTable = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection>>;
176+ using TrksTable = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::TrackSelection, aod::pidTPCFullPi, aod::pidTPCFullKa, aod::pidTPCFullPr, aod::pidTOFbeta, aod::pidTOFFullPi, aod::pidTOFFullKa, aod::pidTOFFullPr >>;
163177 using MftTrkTable = soa::Filtered<aod::MFTTracks>;
164178 using CollTableMC = soa::SmallGroups<soa::Join<aod::McCollisionLabels, aod::Collisions, aod::EvSels, aod::LRMultTables>>;
165179 using TrksTableMC = soa::Filtered<soa::Join<aod::Tracks, aod::TracksExtra, aod::TracksDCA, aod::McTrackLabels, aod::TrackSelection>>;
@@ -184,6 +198,11 @@ struct LongrangeCorrelation {
184198 bool fLoadTrkEffCorr = false ;
185199 bool fLoadMultEffCorr = false ;
186200
201+ std::vector<double > tofNsigmaCut;
202+ std::vector<double > itsNsigmaCut;
203+ std::vector<double > tpcNsigmaCut;
204+ o2::aod::ITSResponse itsResponse;
205+
187206 template <KindOfCorrType corrType, KindOfEvntType evntType>
188207 void addHistos ()
189208 {
@@ -225,6 +244,10 @@ struct LongrangeCorrelation {
225244
226245 std::vector<AxisSpec> userAxis;
227246
247+ tofNsigmaCut = tofNsigmaPidCut;
248+ itsNsigmaCut = itsNsigmaPidCut;
249+ tpcNsigmaCut = tpcNsigmaPidCut;
250+
228251 if (doprocessEventStat) {
229252 histos.add (" QA/EventHist" , " events" , kTH1F , {axisEvent}, false );
230253 histos.add (" QA/VtxZHist" , " v_{z} (cm)" , kTH1F , {axisVtxZ}, false );
@@ -343,14 +366,26 @@ struct LongrangeCorrelation {
343366 }
344367
345368 template <KindOfCorrType corrType, KindOfEvntType evntType, typename TTracks>
346- void fillYield (TTracks tracks)
369+ void fillYieldTpc (TTracks tracks)
370+ {
371+ histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" hMult" ), tracks.size ());
372+ for (auto const & iTrk : tracks) {
373+ if (cfgTrackPid && getTrackPID (iTrk) != cfgTrackPid)
374+ continue ; // if PID is selected, check if the track has the right PID
375+ histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_etavsphi" ), iTrk.phi (), iTrk.eta ());
376+ histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_eta" ), iTrk.eta ());
377+ histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_phi" ), iTrk.phi ());
378+ histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_pt" ), iTrk.pt ());
379+ }
380+ }
381+
382+ template <KindOfCorrType corrType, KindOfEvntType evntType, typename TTracks>
383+ void fillYieldMft (TTracks tracks)
347384 {
348385 histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" hMult" ), tracks.size ());
349386 for (auto const & iTrk : tracks) {
350387 auto phi = iTrk.phi ();
351- if constexpr (corrType == kFT0AMFT ) {
352- o2::math_utils::bringTo02Pi (phi);
353- }
388+ o2::math_utils::bringTo02Pi (phi);
354389 histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_etavsphi" ), phi, iTrk.eta ());
355390 histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_eta" ), iTrk.eta ());
356391 histos.fill (HIST (kCorrType [corrType]) + HIST (kEvntType [evntType]) + HIST (" Trig_phi" ), phi);
@@ -420,6 +455,56 @@ struct LongrangeCorrelation {
420455 return eff;
421456 }
422457
458+ template <typename TTrack>
459+ int getTrackPID (TTrack track)
460+ {
461+ // Computing Nsigma arrays for pion, kaon, and protons
462+ std::array<float , 3 > nSigmaTPC = {track.tpcNSigmaPi (), track.tpcNSigmaKa (), track.tpcNSigmaPr ()};
463+ std::array<float , 3 > nSigmaTOF = {track.tofNSigmaPi (), track.tofNSigmaKa (), track.tofNSigmaPr ()};
464+ 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)};
465+ int pid = -1 ;
466+
467+ std::array<float , 3 > nSigmaToUse = isUseItsPid ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS
468+ std::vector<double > detectorNsigmaCut = isUseItsPid ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS
469+
470+ bool isPion, isKaon, isProton;
471+ bool isDetectedPion = nSigmaToUse[0 ] < detectorNsigmaCut[0 ] && nSigmaToUse[0 ] > detectorNsigmaCut[0 + 3 ];
472+ bool isDetectedKaon = nSigmaToUse[1 ] < detectorNsigmaCut[1 ] && nSigmaToUse[1 ] > detectorNsigmaCut[1 + 3 ];
473+ bool isDetectedProton = nSigmaToUse[2 ] < detectorNsigmaCut[2 ] && nSigmaToUse[2 ] > detectorNsigmaCut[2 + 3 ];
474+
475+ bool isTofPion = nSigmaTOF[0 ] < tofNsigmaCut[0 ] && nSigmaTOF[0 ] > tofNsigmaCut[0 + 3 ];
476+ bool isTofKaon = nSigmaTOF[1 ] < tofNsigmaCut[1 ] && nSigmaTOF[1 ] > tofNsigmaCut[1 + 3 ];
477+ bool isTofProton = nSigmaTOF[2 ] < tofNsigmaCut[2 ] && nSigmaTOF[2 ] > tofNsigmaCut[2 + 3 ];
478+
479+ if (track.pt () > cfgTofPidPtCut && !track.hasTOF ()) {
480+ return 0 ;
481+ } else if (track.pt () > cfgTofPidPtCut && track.hasTOF ()) {
482+ isPion = isTofPion && isDetectedPion;
483+ isKaon = isTofKaon && isDetectedKaon;
484+ isProton = isTofProton && isDetectedProton;
485+ } else {
486+ isPion = isDetectedPion;
487+ isKaon = isDetectedKaon;
488+ isProton = isDetectedProton;
489+ }
490+
491+ if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) {
492+ return 0 ; // more than one particle satisfy the criteria
493+ }
494+
495+ if (isPion) {
496+ pid = PIONS;
497+ } else if (isKaon) {
498+ pid = KAONS;
499+ } else if (isProton) {
500+ pid = PROTONS;
501+ } else {
502+ return 0 ; // no particle satisfies the criteria
503+ }
504+
505+ return pid + 1 ; // shift the pid by 1, 1 = pion, 2 = kaon, 3 = proton
506+ }
507+
423508 template <CorrelationContainer::CFStep step, typename TTarget, typename TTriggers, typename TFT0s>
424509 void fillCorrFt0aGlobal (TTarget target, TTriggers const & triggers, TFT0s const & ft0, bool mixing, float vz, float multiplicity)
425510 {
@@ -428,6 +513,8 @@ struct LongrangeCorrelation {
428513 histos.fill (HIST (" Ft0aGlobal/SE/hMult_used" ), multiplicity);
429514
430515 for (auto const & triggerTrack : triggers) {
516+ if (cfgTrackPid && getTrackPID (triggerTrack) != cfgTrackPid)
517+ continue ; // if PID is selected, check if the track has the right PID
431518 float trkeffw = 1 .0f ;
432519 if (isUseEffCorr)
433520 trkeffw = getTrkEffCorr (triggerTrack.eta (), triggerTrack.pt (), vz);
@@ -474,6 +561,8 @@ struct LongrangeCorrelation {
474561 if (!mixing)
475562 histos.fill (HIST (" Ft0cGlobal/SE/hMult_used" ), multiplicity);
476563 for (auto const & triggerTrack : triggers) {
564+ if (cfgTrackPid && getTrackPID (triggerTrack) != cfgTrackPid)
565+ continue ; // if PID is selected, check if the track has the right PID
477566 float trkeffw = 1 .0f ;
478567 if (isUseEffCorr)
479568 trkeffw = getTrkEffCorr (triggerTrack.eta (), triggerTrack.pt (), vz);
@@ -520,6 +609,8 @@ struct LongrangeCorrelation {
520609 if (!mixing)
521610 histos.fill (HIST (" MftGlobal/SE/hMult_used" ), multiplicity);
522611 for (auto const & triggerTrack : triggers) {
612+ if (cfgTrackPid && getTrackPID (triggerTrack) != cfgTrackPid)
613+ continue ; // if PID is selected, check if the track has the right PID
523614 float trkeffw = 1 .0f ;
524615 if (isUseEffCorr)
525616 trkeffw = getTrkEffCorr (triggerTrack.eta (), triggerTrack.pt (), vz);
@@ -691,7 +782,7 @@ struct LongrangeCorrelation {
691782 auto bc = col.bc_as <aod::BCsWithTimestamps>();
692783 loadEffCorrection (bc.timestamp ());
693784 loadMultCorrection (bc.timestamp ());
694- fillYield <kFT0AGLOBAL , kSE >(tracks);
785+ fillYieldTpc <kFT0AGLOBAL , kSE >(tracks);
695786 const auto & ft0 = col.foundFT0 ();
696787 auto multiplicity = col.multiplicity ();
697788 float multw = getMultEffCorr (multiplicity);
@@ -713,7 +804,7 @@ struct LongrangeCorrelation {
713804 auto bc = col.bc_as <aod::BCsWithTimestamps>();
714805 loadEffCorrection (bc.timestamp ());
715806 loadMultCorrection (bc.timestamp ());
716- fillYield <kFT0CGLOBAL , kSE >(tracks);
807+ fillYieldTpc <kFT0CGLOBAL , kSE >(tracks);
717808 const auto & ft0 = col.foundFT0 ();
718809 auto multiplicity = col.multiplicity ();
719810 float multw = getMultEffCorr (multiplicity);
@@ -734,7 +825,7 @@ struct LongrangeCorrelation {
734825 auto bc = col.bc_as <aod::BCsWithTimestamps>();
735826 loadEffCorrection (bc.timestamp ());
736827 loadMultCorrection (bc.timestamp ());
737- fillYield <kMFTGLOBAL , kSE >(tracks);
828+ fillYieldTpc <kMFTGLOBAL , kSE >(tracks);
738829 auto multiplicity = col.multiplicity ();
739830 float multw = getMultEffCorr (multiplicity);
740831 if (isUseEffCorr)
@@ -751,7 +842,7 @@ struct LongrangeCorrelation {
751842 return ;
752843 }
753844 if (col.has_foundFT0 ()) {
754- fillYield <kFT0AMFT , kSE >(mfttracks);
845+ fillYieldMft <kFT0AMFT , kSE >(mfttracks);
755846 auto bc = col.bc_as <aod::BCsWithTimestamps>();
756847 loadMultCorrection (bc.timestamp ());
757848 const auto & ft0 = col.foundFT0 ();
@@ -808,7 +899,7 @@ struct LongrangeCorrelation {
808899 loadEffCorrection (bc.timestamp ());
809900 loadMultCorrection (bc.timestamp ());
810901 auto slicedTriggerTracks = tracks.sliceBy (perColGlobal, col1.globalIndex ());
811- fillYield <kFT0AGLOBAL , kME >(slicedTriggerTracks);
902+ fillYieldTpc <kFT0AGLOBAL , kME >(slicedTriggerTracks);
812903 const auto & ft0 = col2.foundFT0 ();
813904 auto multiplicity = col1.multiplicity ();
814905 float multw = getMultEffCorr (multiplicity);
@@ -843,7 +934,7 @@ struct LongrangeCorrelation {
843934 loadEffCorrection (bc.timestamp ());
844935 loadMultCorrection (bc.timestamp ());
845936 auto slicedTriggerTracks = tracks.sliceBy (perColGlobal, col1.globalIndex ());
846- fillYield <kFT0CGLOBAL , kME >(slicedTriggerTracks);
937+ fillYieldTpc <kFT0CGLOBAL , kME >(slicedTriggerTracks);
847938 const auto & ft0 = col2.foundFT0 ();
848939 auto multiplicity = col1.multiplicity ();
849940 float multw = getMultEffCorr (multiplicity);
@@ -906,7 +997,7 @@ struct LongrangeCorrelation {
906997 auto bc = col1.bc_as <aod::BCsWithTimestamps>();
907998 loadMultCorrection (bc.timestamp ());
908999 auto slicedTriggerMftTracks = mfttracks.sliceBy (perColMft, col1.globalIndex ());
909- fillYield <kFT0AMFT , kME >(slicedTriggerMftTracks);
1000+ fillYieldMft <kFT0AMFT , kME >(slicedTriggerMftTracks);
9101001 const auto & ft0 = col2.foundFT0 ();
9111002 auto multiplicity = col1.multiplicity ();
9121003 float multw = getMultEffCorr (multiplicity);
0 commit comments