3434#include " Framework/RunningWorkflowInfo.h"
3535#include " Framework/StepTHn.h"
3636#include " Framework/runDataProcessing.h"
37+ #include " ReconstructionDataFormats/PID.h"
3738#include " ReconstructionDataFormats/Track.h"
3839#include < CCDB/BasicCCDBManager.h>
3940
@@ -63,8 +64,36 @@ using namespace o2;
6364using namespace o2 ::framework;
6465using namespace o2 ::framework::expressions;
6566
67+ static constexpr float LongArrayFloat[3 ][20 ] = {{1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 }, {2.1 , 2.2 , 2.3 , -2.1 , -2.2 , -2.3 , 1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 }, {3.1 , 3.2 , 3.3 , -3.1 , -3.2 , -3.3 , 1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 , 1.3 , -1.1 , -1.2 , -1.3 , 1.1 , 1.2 }};
68+
6669struct V0ptHadPiKaProt {
6770
71+ // ITS response
72+ o2::aod::ITSResponse itsResponse;
73+ // Connect to ccdb
74+ Service<ccdb::BasicCCDBManager> ccdb;
75+ Configurable<int64_t > ccdbNoLaterThan{" ccdbNoLaterThan" , std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now ().time_since_epoch ()).count (), " latest acceptable timestamp of creation for the object" };
76+ Configurable<std::string> ccdbUrl{" ccdbUrl" , " http://ccdb-test.cern.ch:8080" , " url of the ccdb repository" };
77+
78+ enum Particles {
79+ PIONS = 0 ,
80+ KAONS,
81+ PROTONS
82+ };
83+ enum ParticleNsigma {
84+ kPionUpCut = 0 ,
85+ kKaonUpCut ,
86+ kProtonUpCut ,
87+ kPionLowCut ,
88+ kKaonLowCut ,
89+ kProtonLowCut
90+ };
91+ enum DetectorType {
92+ kTPC = 0 ,
93+ kTOF ,
94+ kITS
95+ };
96+
6897 Configurable<float > cfgCutVertex{" cfgCutVertex" , 10 .0f , " Accepted z-vertex range" };
6998 Configurable<float > cfgCutTpcChi2NCl{" cfgCutTpcChi2NCl" , 2 .5f , " Maximum TPCchi2NCl" };
7099 Configurable<float > cfgCutItsChi2NCl{" cfgCutItsChi2NCl" , 36 .0f , " Maximum ITSchi2NCl" };
@@ -92,11 +121,11 @@ struct V0ptHadPiKaProt {
92121 Configurable<bool > cfgUseGoodITSLayerAllCut{" cfgUseGoodITSLayerAllCut" , true , " Remove time interval with dead ITS zone" };
93122 Configurable<bool > cfgEvSelkNoITSROFrameBorder{" cfgEvSelkNoITSROFrameBorder" , true , " ITSROFrame border event selection cut" };
94123 Configurable<bool > cfgEvSelkNoTimeFrameBorder{" cfgEvSelkNoTimeFrameBorder" , true , " TimeFrame border event selection cut" };
95-
96- // Connect to ccdb
97- Service<ccdb::BasicCCDBManager> ccdb ;
98- Configurable<int64_t > ccdbNoLaterThan{ " ccdbNoLaterThan " , std::chrono::duration_cast<std::chrono::milliseconds>( std::chrono::system_clock::now (). time_since_epoch ()). count (), " latest acceptable timestamp of creation for the object " };
99- Configurable<std::string> ccdbUrl{ " ccdbUrl " , " http://ccdb-test.cern.ch:8080 " , " url of the ccdb repository " };
124+ Configurable< bool > cfgEvSelUseGoodZvtxFT0vsPV{ " cfgEvSelUseGoodZvtxFT0vsPV " , true , " GoodZvertex and FT0 vs PV cut " };
125+ Configurable< bool > cfgUseItsPID{ " cfgUseItsPID " , false , " Use ITS PID for particle identification " };
126+ Configurable< float > cfgPtCutTOF{ " cfgPtCutTOF " , 0 . 3f , " Minimum pt to use TOF N-sigma " } ;
127+ Configurable<LabeledArray< float >> nSigmas{ " nSigmas " , {LongArrayFloat[ 0 ], 3 , 6 , { " TPC " , " TOF " , " ITS " }, { " pos_pi " , " pos_ka " , " pos_pr " , " neg_pi " , " neg_ka " , " neg_pr " }}, " Labeled array for n-sigma values for TPC, TOF, ITS for pions, kaons, protons (positive and negative) " };
128+ Configurable<bool > cfgUseRun3V2PID{ " cfgUseRun3V2PID " , true , " True if PID cuts to be used are similar to Run3 v2 PID analysis " };
100129
101130 HistogramRegistry histos{" Histos" , {}, OutputObjHandlingPolicy::AnalysisObject};
102131 std::vector<std::vector<std::shared_ptr<TProfile2D>>> subSample;
@@ -110,9 +139,35 @@ struct V0ptHadPiKaProt {
110139 using AodCollisions = soa::Filtered<soa::Join<aod::Collisions, aod::EvSels, aod::CentFV0As, aod::CentFT0Ms, aod::CentFT0As, aod::CentFT0Cs, aod::CentFDDMs, aod::Mults>>;
111140 using AodTracks = soa::Filtered<soa::Join<aod::Tracks, aod::TrackSelection, aod::TracksExtra, aod::TracksDCA, aod::pidTPCFullPr, aod::pidTOFFullPr, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullEl, aod::pidTOFFullEl>>;
112141
142+ std::array<float , 6 > tofNsigmaCut;
143+ std::array<float , 6 > itsNsigmaCut;
144+ std::array<float , 6 > tpcNsigmaCut;
145+
113146 // Equivalent of the AliRoot task UserCreateOutputObjects
114147 void init (o2::framework::InitContext&)
115148 {
149+ // Get nSigma values of TPC, TOF, ITS for various particles from the matrix "nSigmas"
150+ tpcNsigmaCut[kPionUpCut ] = nSigmas->getData ()[kTPC ][kPionUpCut ];
151+ tpcNsigmaCut[kKaonUpCut ] = nSigmas->getData ()[kTPC ][kKaonUpCut ];
152+ tpcNsigmaCut[kProtonUpCut ] = nSigmas->getData ()[kTPC ][kProtonUpCut ];
153+ tpcNsigmaCut[kPionLowCut ] = nSigmas->getData ()[kTPC ][kPionLowCut ];
154+ tpcNsigmaCut[kKaonLowCut ] = nSigmas->getData ()[kTPC ][kKaonLowCut ];
155+ tpcNsigmaCut[kProtonLowCut ] = nSigmas->getData ()[kTPC ][kProtonLowCut ];
156+
157+ tofNsigmaCut[kPionUpCut ] = nSigmas->getData ()[kTOF ][kPionUpCut ];
158+ tofNsigmaCut[kKaonUpCut ] = nSigmas->getData ()[kTOF ][kKaonUpCut ];
159+ tofNsigmaCut[kProtonUpCut ] = nSigmas->getData ()[kTOF ][kProtonUpCut ];
160+ tofNsigmaCut[kPionLowCut ] = nSigmas->getData ()[kTOF ][kPionLowCut ];
161+ tofNsigmaCut[kKaonLowCut ] = nSigmas->getData ()[kTOF ][kKaonLowCut ];
162+ tofNsigmaCut[kProtonLowCut ] = nSigmas->getData ()[kTOF ][kProtonLowCut ];
163+
164+ itsNsigmaCut[kPionUpCut ] = nSigmas->getData ()[kITS ][kPionUpCut ];
165+ itsNsigmaCut[kKaonUpCut ] = nSigmas->getData ()[kITS ][kKaonUpCut ];
166+ itsNsigmaCut[kProtonUpCut ] = nSigmas->getData ()[kITS ][kProtonUpCut ];
167+ itsNsigmaCut[kPionLowCut ] = nSigmas->getData ()[kITS ][kPionLowCut ];
168+ itsNsigmaCut[kKaonLowCut ] = nSigmas->getData ()[kITS ][kKaonLowCut ];
169+ itsNsigmaCut[kProtonLowCut ] = nSigmas->getData ()[kITS ][kProtonLowCut ];
170+
116171 // Define axes
117172 std::vector<double > ptBin = {0.2 , 0.4 , 0.6 , 0.8 , 1.0 , 1.2 , 1.4 , 1.6 , 1.8 , 2.0 , 2.2 , 2.4 , 2.6 , 2.8 , 3.0 , 3.5 , 4.0 , 5.0 , 6.0 , 8.0 , 10.0 };
118173 AxisSpec ptAxis = {ptBin, " #it{p}_{T} (GeV/#it{c})" };
@@ -332,6 +387,56 @@ struct V0ptHadPiKaProt {
332387 return false ;
333388 }
334389
390+ template <typename TTrack>
391+ int getNsigmaPID (TTrack track)
392+ {
393+ // Computing Nsigma arrays for pion, kaon, and protons
394+ std::array<float , 3 > nSigmaTPC = {track.tpcNSigmaPi (), track.tpcNSigmaKa (), track.tpcNSigmaPr ()};
395+ std::array<float , 3 > nSigmaTOF = {track.tofNSigmaPi (), track.tofNSigmaKa (), track.tofNSigmaPr ()};
396+ 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)};
397+ int pid = 0 ; // 0 = not identified, 1 = pion, 2 = kaon, 3 = proton
398+
399+ std::array<float , 3 > nSigmaToUse = cfgUseItsPID ? nSigmaITS : nSigmaTPC; // Choose which nSigma to use: TPC or ITS
400+ std::array<float , 6 > detectorNsigmaCut = cfgUseItsPID ? itsNsigmaCut : tpcNsigmaCut; // Choose which nSigma to use: TPC or ITS
401+
402+ bool isPion, isKaon, isProton;
403+ bool isDetectedPion = nSigmaToUse[PIONS] < detectorNsigmaCut[kPionUpCut ] && nSigmaToUse[PIONS] > detectorNsigmaCut[kPionLowCut ];
404+ bool isDetectedKaon = nSigmaToUse[KAONS] < detectorNsigmaCut[kKaonUpCut ] && nSigmaToUse[KAONS] > detectorNsigmaCut[kKaonLowCut ];
405+ bool isDetectedProton = nSigmaToUse[PROTONS] < detectorNsigmaCut[kProtonUpCut ] && nSigmaToUse[PROTONS] > detectorNsigmaCut[kProtonLowCut ];
406+
407+ bool isTofPion = nSigmaTOF[PIONS] < tofNsigmaCut[kPionUpCut ] && nSigmaTOF[PIONS] > tofNsigmaCut[kPionLowCut ];
408+ bool isTofKaon = nSigmaTOF[KAONS] < tofNsigmaCut[kKaonUpCut ] && nSigmaTOF[KAONS] > tofNsigmaCut[kKaonLowCut ];
409+ bool isTofProton = nSigmaTOF[PROTONS] < tofNsigmaCut[kProtonUpCut ] && nSigmaTOF[PROTONS] > tofNsigmaCut[kProtonLowCut ];
410+
411+ if (track.pt () > cfgPtCutTOF && !track.hasTOF ()) {
412+ return 0 ;
413+ } else if (track.pt () > cfgPtCutTOF && track.hasTOF ()) {
414+ isPion = isTofPion && isDetectedPion;
415+ isKaon = isTofKaon && isDetectedKaon;
416+ isProton = isTofProton && isDetectedProton;
417+ } else {
418+ isPion = isDetectedPion;
419+ isKaon = isDetectedKaon;
420+ isProton = isDetectedProton;
421+ }
422+
423+ if ((isPion && isKaon) || (isPion && isProton) || (isKaon && isProton)) {
424+ return 0 ; // more than one particle satisfy the criteria
425+ }
426+
427+ if (isPion) {
428+ pid = PIONS + 1 ;
429+ } else if (isKaon) {
430+ pid = KAONS + 1 ;
431+ } else if (isProton) {
432+ pid = PROTONS + 1 ;
433+ } else {
434+ return 0 ; // no particle satisfies the criteria
435+ }
436+
437+ return pid; // 0 = not identified, 1 = pion, 2 = kaon, 3 = proton
438+ }
439+
335440 // process Data
336441 void process (AodCollisions::iterator const & coll, aod::BCsWithTimestamps const &, AodTracks const & inputTracks)
337442 {
@@ -350,6 +455,9 @@ struct V0ptHadPiKaProt {
350455 if (cfgEvSelkNoTimeFrameBorder && !(coll.selection_bit (o2::aod::evsel::kNoTimeFrameBorder ))) {
351456 return ;
352457 }
458+ if (cfgEvSelUseGoodZvtxFT0vsPV && !(coll.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV ))) {
459+ return ;
460+ }
353461
354462 // Centrality
355463 double cent = 0.0 ;
@@ -438,9 +546,23 @@ struct V0ptHadPiKaProt {
438546 histos.fill (HIST (" h2DnsigmaProtonTpcVsTofBeforeCut" ), nSigmaTpcProt, nSigmaTofProt);
439547
440548 // identified particles selection
441- bool isPion = selectionPion (track);
442- bool isKaon = selectionKaon (track);
443- bool isProton = selectionProton (track);
549+ bool isPion = false ;
550+ bool isKaon = false ;
551+ bool isProton = false ;
552+
553+ if (cfgUseRun3V2PID) {
554+ int pidVal = getNsigmaPID (track);
555+ if (pidVal == 1 )
556+ isPion = true ;
557+ if (pidVal == 2 )
558+ isKaon = true ;
559+ if (pidVal == 3 )
560+ isProton = true ;
561+ } else {
562+ isPion = selectionPion (track);
563+ isKaon = selectionKaon (track);
564+ isProton = selectionProton (track);
565+ }
444566
445567 // PID QAs after selection
446568 if (isPion) {
0 commit comments