@@ -133,6 +133,36 @@ struct HfDataCreatorJpsiHadReduced {
133133 Configurable<double > minRelChi2Change{" minRelChi2Change" , 0.9 , " stop iterations is chi2/chi2old > this" };
134134
135135 Configurable<bool > runJpsiToee{" runJpsiToee" , false , " Run analysis for J/Psi to ee (debug)" };
136+ struct : o2::framework::ConfigurableGroup {
137+ // TPC PID
138+ Configurable<double > ptPidTpcMin{" ptPidTpcMin" , 0.15 , " Lower bound of track pT for TPC PID" };
139+ Configurable<double > ptPidTpcMax{" ptPidTpcMax" , 5 ., " Upper bound of track pT for TPC PID" };
140+ Configurable<double > nSigmaTpcElMax{" nSigmaTpcElMax" , 4 ., " Electron nsigma cut on TPC only" };
141+ Configurable<double > nSigmaTpcPiMin{" nSigmaTpcPiMin" , 2.5 , " Pion nsigma cut on TPC only" };
142+ Configurable<double > nSigmaTpcPiMax{" nSigmaTpcPiMax" , 99 ., " Pion nsigma cut on TPC only" };
143+ Configurable<double > nSigmaTpcPrMin{" nSigmaTpcPrMin" , -99 ., " Proton nsigma cut on TPC only" };
144+ Configurable<double > nSigmaTpcPrMax{" nSigmaTpcPrMax" , 99 , " Proton nsigma cut on TPC only" };
145+ Configurable<double > nSigmaTpcElCombinedMax{" nSigmaTpcElCombinedMax" , 4 ., " Electron Nsigma cut on TPC combined with TOF" };
146+ Configurable<double > nSigmaTpcPiCombinedMin{" nSigmaTpcPiCombinedMin" , 2.5 , " Pion Nsigma cut on TPC combined with TOF" };
147+ Configurable<double > nSigmaTpcPiCombinedMax{" nSigmaTpcPiCombinedMax" , 99 ., " Pion Nsigma cut on TPC combined with TOF" };
148+ Configurable<double > nSigmaTpcPrCombinedMin{" nSigmaTpcPrCombinedMin" , -99 ., " Proton Nsigma cut on TPC combined with TOF" };
149+ Configurable<double > nSigmaTpcPrCombinedMax{" nSigmaTpcPrCombinedMax" , 99 , " Proton Nsigma cut on TPC combined with TOF" };
150+ // TOF PID
151+ Configurable<double > ptPidTofMin{" ptPidTofMin" , 0.15 , " Lower bound of track pT for TOF PID" };
152+ Configurable<double > ptPidTofMax{" ptPidTofMax" , 5 ., " Upper bound of track pT for TOF PID" };
153+ Configurable<double > nSigmaTofElMax{" nSigmaTofElMax" , 4 ., " Electron nsigma cut on TPC only" };
154+ Configurable<double > nSigmaTofPiMin{" nSigmaTofPiMin" , -99 , " Pion nsigma cut on TPC only" };
155+ Configurable<double > nSigmaTofPiMax{" nSigmaTofPiMax" , 99 ., " Pion nsigma cut on TPC only" };
156+ Configurable<double > nSigmaTofPrMin{" nSigmaTofPrMin" , -99 , " Proton nsigma cut on TPC only" };
157+ Configurable<double > nSigmaTofPrMax{" nSigmaTofPrMax" , 99 ., " Proton nsigma cut on TPC only" };
158+ Configurable<double > nSigmaTofElCombinedMax{" nSigmaTofElCombinedMax" , 4 ., " Electron Nsigma cut on TOF combined with TPC" };
159+ Configurable<double > nSigmaTofPiCombinedMin{" nSigmaTofPiCombinedMin" , 2.5 , " Pion Nsigma cut on TOF combined with TPC" };
160+ Configurable<double > nSigmaTofPiCombinedMax{" nSigmaTofPiCombinedMax" , 99 ., " Pion Nsigma cut on TOF combined with TPC" };
161+ Configurable<double > nSigmaTofPrCombinedMin{" nSigmaTofPrCombinedMin" , -99 ., " Proton Nsigma cut on TOF combined with TPC" };
162+ Configurable<double > nSigmaTofPrCombinedMax{" nSigmaTofPrCombinedMax" , 99 , " Proton Nsigma cut on TOF combined with TPC" };
163+ // AND logic for TOF+TPC PID (as in Run2)
164+ Configurable<bool > usePidTpcAndTof{" usePidTpcAndTof" , true , " Use AND logic for TPC and TOF PID" };
165+ } selectionsPid;
136166 Configurable<double > ptJpsiMin{" ptJpsiMin" , 0 ., " Lower bound of J/Psi pT" };
137167 Configurable<double > ptJpsiMax{" ptJpsiMax" , 50 ., " Upper bound of J/Psi pT" };
138168 Configurable<bool > useTrackIsGlobalTrackWoDCA{" useTrackIsGlobalTrackWoDCA" , true , " check isGlobalTrackWoDCA status for the bachelor tracks" };
@@ -154,22 +184,25 @@ struct HfDataCreatorJpsiHadReduced {
154184
155185 HfHelper hfHelper;
156186
187+ TrackSelectorPi selectorPion;
188+ TrackSelectorPr selectorProton;
189+ TrackSelectorEl selectorElectron;
190+
157191 // CCDB service
158192 Service<o2::ccdb::BasicCCDBManager> ccdb;
159193 // O2DatabasePDG service
160194 Service<o2::framework::O2DatabasePDG> pdg;
161195
162- using TracksPid = soa::Join<aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr>;
196+ using TracksPid = soa::Join<aod::pidTPCFullPi, aod::pidTOFFullPi, aod::pidTPCFullKa, aod::pidTOFFullKa, aod::pidTPCFullPr, aod::pidTOFFullPr, aod::pidTPCFullEl, aod::pidTOFFullEl >;
163197 using TracksPidWithSel = soa::Join<aod::TracksWCovDcaExtra, TracksPid, aod::TrackSelection>;
164- using TracksSel = soa::Join<aod::TracksWDcaExtra, aod::TracksPidPi, aod::PidTpcTofFullPi, aod::TracksPidKa, aod::PidTpcTofFullKa>;
165198 using TracksPidWithSelAndMc = soa::Join<TracksPidWithSel, aod::McTrackLabels>;
166199 using CollisionsWCMcLabels = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels>;
167200 using BCsInfo = soa::Join<aod::BCsWithTimestamps, aod::BcSels>;
168201
169202 Preslice<aod::HfCand2ProngWPid> candsJpsiPerCollision = aod::track_association::collisionId;
170203 Preslice<aod::TrackAssoc> trackIndicesPerCollision = aod::track_association::collisionId;
171- PresliceUnsorted<CollisionsWCMcLabels> colPerMcCollision = aod::mccollisionlabel::mcCollisionId;
172204 Preslice<aod::McParticles> mcParticlesPerMcCollision = aod::mcparticle::mcCollisionId;
205+ PresliceUnsorted<CollisionsWCMcLabels> colPerMcCollision = aod::mccollisionlabel::mcCollisionId;
173206
174207 o2::base::Propagator::MatCorrType noMatCorr = o2::base::Propagator::MatCorrType::USEMatCorrNONE;
175208 int runNumber;
@@ -188,17 +221,39 @@ struct HfDataCreatorJpsiHadReduced {
188221
189222 void init (InitContext& initContext)
190223 {
224+ selectorPion.setRangePtTpc (selectionsPid.ptPidTpcMin , selectionsPid.ptPidTpcMax );
225+ selectorPion.setRangeNSigmaTpc (-selectionsPid.nSigmaTpcPiMax , selectionsPid.nSigmaTpcPiMax );
226+ selectorPion.setRangeNSigmaTpcCondTof (-selectionsPid.nSigmaTpcPiCombinedMax , selectionsPid.nSigmaTpcPiCombinedMax );
227+ selectorPion.setRangePtTof (selectionsPid.ptPidTofMin , selectionsPid.ptPidTofMax );
228+ selectorPion.setRangeNSigmaTof (-selectionsPid.nSigmaTofPiMax , selectionsPid.nSigmaTofPiMax );
229+ selectorPion.setRangeNSigmaTofCondTpc (-selectionsPid.nSigmaTofPiCombinedMax , selectionsPid.nSigmaTofPiCombinedMax );
230+
231+ selectorProton.setRangePtTpc (selectionsPid.ptPidTpcMin , selectionsPid.ptPidTpcMax );
232+ selectorProton.setRangeNSigmaTpc (-selectionsPid.nSigmaTpcPrMax , selectionsPid.nSigmaTpcPrMax );
233+ selectorProton.setRangeNSigmaTpcCondTof (-selectionsPid.nSigmaTpcPrCombinedMax , selectionsPid.nSigmaTpcPrCombinedMax );
234+ selectorProton.setRangePtTof (selectionsPid.ptPidTofMin , selectionsPid.ptPidTofMax );
235+ selectorProton.setRangeNSigmaTof (-selectionsPid.nSigmaTofPrMax , selectionsPid.nSigmaTofPrMax );
236+ selectorProton.setRangeNSigmaTofCondTpc (-selectionsPid.nSigmaTofPrCombinedMax , selectionsPid.nSigmaTofPrCombinedMax );
237+
238+ selectorElectron.setRangePtTpc (selectionsPid.ptPidTpcMin , selectionsPid.ptPidTpcMax );
239+ selectorElectron.setRangeNSigmaTpc (-selectionsPid.nSigmaTpcElMax , selectionsPid.nSigmaTpcElMax );
240+ selectorElectron.setRangeNSigmaTpcCondTof (-selectionsPid.nSigmaTofElCombinedMax , selectionsPid.nSigmaTofElCombinedMax );
241+ selectorElectron.setRangePtTof (selectionsPid.ptPidTofMin , selectionsPid.ptPidTofMax );
242+ selectorElectron.setRangeNSigmaTof (-selectionsPid.nSigmaTofElMax , selectionsPid.nSigmaTofElMax );
243+ selectorElectron.setRangeNSigmaTofCondTpc (-selectionsPid.nSigmaTofElCombinedMax , selectionsPid.nSigmaTofElCombinedMax );
244+
191245 std::array<int , 4 > doProcess = {doprocessJpsiKData, doprocessJpsiKMc, doprocessJpsiPhiData, doprocessJpsiPhiMc};
192246 if (std::accumulate (doProcess.begin (), doProcess.end (), 0 ) != 1 ) {
193247 LOGP (fatal, " One and only one process function can be enabled at a time, please fix your configuration!" );
194248 }
195249
196250 // Set up the histogram registry
197- constexpr int kNBinsSelections = 2 + aod::SelectionStep::RecoTopol ;
251+ constexpr int kNBinsSelections = 2 + aod::SelectionStep::RecoPID ;
198252 std::string labels[kNBinsSelections ];
199253 labels[0 ] = " No selection" ;
200254 labels[1 + aod::SelectionStep::RecoSkims] = " Skims selection" ;
201255 labels[1 + aod::SelectionStep::RecoTopol] = " Skims & Topological selections" ;
256+ labels[1 + aod::SelectionStep::RecoPID] = " Skims & Topological & PID selections" ;
202257 static const AxisSpec axisSelections = {kNBinsSelections , 0.5 , kNBinsSelections + 0.5 , " " };
203258 registry.add (" hSelectionsJpsi" , " J/Psi selection;;#it{p}_{T} (GeV/#it{c})" , {HistType::kTH2F , {axisSelections, {(std::vector<double >)binsPt, " #it{p}_{T} (GeV/#it{c})" }}});
204259 for (int iBin = 0 ; iBin < kNBinsSelections ; ++iBin) {
@@ -382,6 +437,31 @@ struct HfDataCreatorJpsiHadReduced {
382437 return true ;
383438 }
384439
440+ template <typename T1>
441+ bool isSelectedJpsiDauPid (const T1& track)
442+ {
443+ int pidPion = -1 ;
444+ int pidProton = -1 ;
445+ int pidElectron = -1 ;
446+
447+ if (selectionsPid.usePidTpcAndTof ) {
448+ pidPion = selectorPion.statusTpcAndTof (track, track.tpcNSigmaPi (), track.tofNSigmaPi ());
449+ pidProton = selectorProton.statusTpcAndTof (track, track.tpcNSigmaPr (), track.tofNSigmaPr ());
450+ pidElectron = selectorElectron.statusTpcAndTof (track, track.tpcNSigmaEl (), track.tofNSigmaEl ());
451+ } else {
452+ pidPion = selectorPion.statusTpcOrTof (track, track.tpcNSigmaPi (), track.tofNSigmaPi ());
453+ pidProton = selectorProton.statusTpcOrTof (track, track.tpcNSigmaPr (), track.tofNSigmaPr ());
454+ pidElectron = selectorElectron.statusTpcOrTof (track, track.tpcNSigmaEl (), track.tofNSigmaEl ());
455+ }
456+
457+ if (pidPion == TrackSelectorPID::Rejected ||
458+ pidProton == TrackSelectorPID::Rejected ||
459+ pidElectron == TrackSelectorPID::Rejected) {
460+ return false ;
461+ }
462+ return true ;
463+ }
464+
385465 // / B meson preselections
386466 // / \param momentum is the B meson momentum
387467 // / \param secondaryVertex is the reconstructed secondary vertex
@@ -735,6 +815,12 @@ struct HfDataCreatorJpsiHadReduced {
735815 }
736816 registry.fill (HIST (" hSelectionsJpsi" ), 2 + aod::SelectionStep::RecoTopol, candidate.pt ());
737817
818+ // PID selection
819+ if (!isSelectedJpsiDauPid (trackPos) || !isSelectedJpsiDauPid (trackNeg)) {
820+ continue ;
821+ }
822+ registry.fill (HIST (" hSelectionsJpsi" ), 2 + aod::SelectionStep::RecoPID, candidate.pt ());
823+
738824 int indexHfCandJpsi = hfJpsi.lastIndex () + 1 ;
739825 float invMassJpsi{0 .f };
740826 if (runJpsiToee) {
@@ -811,7 +897,7 @@ struct HfDataCreatorJpsiHadReduced {
811897 trackParCovBach.getX (), trackParCovBach.getAlpha (),
812898 trackParCovBach.getY (), trackParCovBach.getZ (), trackParCovBach.getSnp (),
813899 trackParCovBach.getTgl (), trackParCovBach.getQ2Pt (),
814- trackBach.itsNCls (), trackBach.tpcNClsCrossedRows (), trackBach.tpcChi2NCl (),
900+ trackBach.itsNCls (), trackBach.tpcNClsCrossedRows (), trackBach.tpcChi2NCl (), trackBach. itsChi2NCl (),
815901 trackBach.hasTPC (), trackBach.hasTOF (),
816902 trackBach.tpcNSigmaPi (), trackBach.tofNSigmaPi (),
817903 trackBach.tpcNSigmaKa (), trackBach.tofNSigmaKa (),
@@ -908,7 +994,7 @@ struct HfDataCreatorJpsiHadReduced {
908994 trackParCovBach.getX (), trackParCovBach.getAlpha (),
909995 trackParCovBach.getY (), trackParCovBach.getZ (), trackParCovBach.getSnp (),
910996 trackParCovBach.getTgl (), trackParCovBach.getQ2Pt (),
911- trackBach.itsNCls (), trackBach.tpcNClsCrossedRows (), trackBach.tpcChi2NCl (),
997+ trackBach.itsNCls (), trackBach.tpcNClsCrossedRows (), trackBach.tpcChi2NCl (), trackBach. itsChi2NCl (),
912998 trackBach.hasTPC (), trackBach.hasTOF (),
913999 trackBach.tpcNSigmaPi (), trackBach.tofNSigmaPi (),
9141000 trackBach.tpcNSigmaKa (), trackBach.tofNSigmaKa (),
@@ -932,7 +1018,7 @@ struct HfDataCreatorJpsiHadReduced {
9321018 trackBach2ParCov.getX (), trackBach2ParCov.getAlpha (),
9331019 trackBach2ParCov.getY (), trackBach2ParCov.getZ (), trackBach2ParCov.getSnp (),
9341020 trackBach2ParCov.getTgl (), trackBach2ParCov.getQ2Pt (),
935- trackBach2.itsNCls (), trackBach2.tpcNClsCrossedRows (), trackBach2.tpcChi2NCl (),
1021+ trackBach2.itsNCls (), trackBach2.tpcNClsCrossedRows (), trackBach2.tpcChi2NCl (), trackBach2. itsChi2NCl (),
9361022 trackBach2.hasTPC (), trackBach2.hasTOF (),
9371023 trackBach2.tpcNSigmaPi (), trackBach2.tofNSigmaPi (),
9381024 trackBach2.tpcNSigmaKa (), trackBach2.tofNSigmaKa (),
@@ -972,6 +1058,8 @@ struct HfDataCreatorJpsiHadReduced {
9721058 indexHfReducedCollision,
9731059 candidate.xSecondaryVertex (), candidate.ySecondaryVertex (), candidate.zSecondaryVertex (),
9741060 invMassJpsi,
1061+ trackPos.itsNCls (), trackPos.tpcNClsCrossedRows (), trackPos.tpcChi2NCl (), trackPos.itsChi2NCl (),
1062+ trackNeg.itsNCls (), trackNeg.tpcNClsCrossedRows (), trackNeg.tpcChi2NCl (), trackNeg.itsChi2NCl (),
9751063 trackPosParCov.getX (), trackNegParCov.getX (),
9761064 trackPosParCov.getY (), trackNegParCov.getY (),
9771065 trackPosParCov.getZ (), trackNegParCov.getZ (),
0 commit comments