1313// / \brief Delta(1232) resonance analysis via proton-pion invariant mass reconstruction with advance PID and background rejection cuts
1414// / \author Durgesh Bhatt <durgesh.bhatt@cern.ch>
1515
16+ #include " Common/CCDB/EventSelectionParams.h"
1617#include " Common/Core/RecoDecay.h"
1718#include " Common/DataModel/Centrality.h"
1819#include " Common/DataModel/EventSelection.h"
@@ -78,6 +79,10 @@ struct DeltaAnalysis {
7879
7980 // FIX name/configurable: single space between type and name; member name == JSON key; lowerCamelCase
8081 Configurable<float > cfgCutVertex{" cfgCutVertex" , 10 .0f , " Accepted |z-vertex| range [cm]" };
82+
83+ Configurable<bool > cfgUseNoSameBunchPileupCut{" cfgUseNoSameBunchPileupCut" , false , " Apply kNoSameBunchPileup event selection" };
84+
85+ Configurable<bool > cfgUseGoodZvtxFT0vsPVCut{" cfgUseGoodZvtxFT0vsPVCut" , false , " Apply kIsGoodZvtxFT0vsPV event selection" };
8186 Configurable<bool > applyOccupancyInTimeRangeCut{" applyOccupancyInTimeRangeCut" , false , " Apply occupancy-in-time-range cut" };
8287 Configurable<int > cfgOccupancyMin{" cfgOccupancyMin" , 0 , " Minimum track occupancy in time range" };
8388 Configurable<int > cfgOccupancyMax{" cfgOccupancyMax" , 9999 , " Maximum track occupancy in time range" };
@@ -103,6 +108,7 @@ struct DeltaAnalysis {
103108 Configurable<bool > requirePrimaryTrack{" requirePrimaryTrack" , true , " Require isPrimaryTrack flag" };
104109 Configurable<bool > requireGlobalTrackNoDCA{" requireGlobalTrackNoDCA" , true , " Require isGlobalTrackWoDCA flag" };
105110 Configurable<bool > requirePVContributor{" requirePVContributor" , true , " Require PV-contributor flag" };
111+ Configurable<float > cfgLowPtTofNsigmaCut{" cfgLowPtTofNsigmaCut" , 3 .0f , " Low pt nSigma TOF cut for selecting pions and protons" };
106112
107113 Configurable<float > cfgCutDCAz{" cfgCutDCAz" , 0 .1f , " Maximum |DCAz| for all tracks [cm]" };
108114 Configurable<std::vector<float >> protonDCAPtBinEdges{" protonDCAPtBinEdges" , {0 .0f , 0 .5f , 1 .0f , 2 .0f , 1000 .f }, " Proton pT bin edges for DCAxy cut [GeV/c]" };
@@ -113,6 +119,7 @@ struct DeltaAnalysis {
113119 Configurable<bool > useTPCOnlyPID{" useTPCOnlyPID" , false , " Use TPC-only PID (ignore TOF even if present)" };
114120 Configurable<bool > requireTOFForProton{" requireTOFForProton" , false , " Require TOF signal for proton candidates" };
115121 Configurable<bool > requireTOFForPion{" requireTOFForPion" , false , " Require TOF signal for pion candidates" };
122+ Configurable<bool > applyTOFCutWhenAvailableBelowThreshold{" applyTOFCutWhenAvailableBelowThreshold" , false , " Apply TOF PID only when TOF information exists below momentum threshold" };
116123
117124 Configurable<float > minProtonMomentum{" minProtonMomentum" , 0 .f , " Minimum proton momentum for TOF PID [GeV/c]" };
118125 Configurable<float > minTPCNSigmaProton{" minTPCNSigmaProton" , -6 .0f , " Minimum (lower bound) TPC nSigma for proton" };
@@ -198,7 +205,7 @@ struct DeltaAnalysis {
198205 mPionMaxDCAxy = pionMaxDCAxyPerPtBin.value ;
199206
200207 const AxisSpec ptAxis{200 , 0 ., 10 ., " p_{T} (GeV/c)" };
201- const AxisSpec massAxis{numberOfInvMassBins, 0.8 , 1.8 , " M_{inv} (GeV/#it{c}^{2})" };
208+ const AxisSpec massAxis{numberOfInvMassBins, 1.0 , 8.0 , " M_{inv} (GeV/#it{c}^{2})" };
202209 const AxisSpec centAxis{cfgCentAxis, " Centrality (%)" };
203210 const AxisSpec vtxAxis{cfgVtxAxis, " Vertex z [cm]" };
204211 const AxisSpec rapAxis{cfgRapAxis, " Rapidity y" };
@@ -367,6 +374,7 @@ struct DeltaAnalysis {
367374 }
368375 }
369376
377+ // passesEventSelection with optional EventSelection cuts
370378 template <typename CollisionType>
371379 bool passesEventSelection (CollisionType const & collision)
372380 {
@@ -382,6 +390,16 @@ struct DeltaAnalysis {
382390 const float cent = getCentrality (collision);
383391 if (cent < cfgCentMin || cent > cfgCentMax)
384392 return false ;
393+
394+ if (cfgUseNoSameBunchPileupCut &&
395+ !collision.selection_bit (o2::aod::evsel::kNoSameBunchPileup )) {
396+ return false ;
397+ }
398+
399+ if (cfgUseGoodZvtxFT0vsPVCut &&
400+ !collision.selection_bit (o2::aod::evsel::kIsGoodZvtxFT0vsPV )) {
401+ return false ;
402+ }
385403 return true ;
386404 }
387405
@@ -480,19 +498,32 @@ struct DeltaAnalysis {
480498 tofPassed = true ;
481499 }
482500 }
501+ // ── Part 2: low-momentum region with TOF available ──────────────────
483502 if (totalMomentum < minProtonMomentum && tpcNSigPr < static_cast <float >(maxTPCNSigmaProton)) {
484503 tpcPassed = true ;
485- tofPassed = true ;
504+ if (applyTOFCutWhenAvailableBelowThreshold) {
505+ // TOF is available (track.hasTOF() is true in this branch): require TOF nSigma
506+ tofPassed = (tofNSigPr < cfgLowPtTofNsigmaCut);
507+ } else {
508+ tofPassed = true ;
509+ }
486510 }
487511 } else {
488- tofPassed = true ;
489- if (track.tpcNSigmaPr () < minTPCNSigmaProton)
490- return false ;
491- for (int i = 0 ; i < nTPCBins - 1 ; ++i) {
492- if (totalMomentum >= mProtonTPCMomBins [i] && totalMomentum < mProtonTPCMomBins [i + 1 ] &&
493- tpcNSigPr < mProtonTPCNSigCuts [i] && tpcNSigPi > tpcNSigmaVetoThreshold) {
494- tpcPassed = true ;
495- break ;
512+ // No TOF available (or useTPCOnlyPID == true)
513+ if (totalMomentum < minProtonMomentum && tpcNSigPr < static_cast <float >(maxTPCNSigmaProton)) {
514+ // ── Part 2: low-momentum, no TOF → TPC-only regardless of configurable ──
515+ tpcPassed = true ;
516+ tofPassed = true ;
517+ } else {
518+ tofPassed = true ;
519+ if (track.tpcNSigmaPr () < minTPCNSigmaProton)
520+ return false ;
521+ for (int i = 0 ; i < nTPCBins - 1 ; ++i) {
522+ if (totalMomentum >= mProtonTPCMomBins [i] && totalMomentum < mProtonTPCMomBins [i + 1 ] &&
523+ tpcNSigPr < mProtonTPCNSigCuts [i] && tpcNSigPi > tpcNSigmaVetoThreshold) {
524+ tpcPassed = true ;
525+ break ;
526+ }
496527 }
497528 }
498529 }
@@ -535,19 +566,32 @@ struct DeltaAnalysis {
535566 tofPassed = true ;
536567 }
537568 }
569+ // ── Part 2: low-momentum region with TOF available ──────────────────
538570 if (totalMomentum < minPionMomentum && tpcNSigPi < static_cast <float >(maxTPCNSigmaPion)) {
539571 tpcPassed = true ;
540- tofPassed = true ;
572+ if (applyTOFCutWhenAvailableBelowThreshold) {
573+ // TOF is available (track.hasTOF() is true in this branch): require TOF nSigma
574+ tofPassed = (tofNSigPi < cfgLowPtTofNsigmaCut);
575+ } else {
576+ tofPassed = true ;
577+ }
541578 }
542579 } else {
543- tofPassed = true ;
544- if (track.tpcNSigmaPi () < minTPCNSigmaPion)
545- return false ;
546- for (int i = 0 ; i < nTPCBins - 1 ; ++i) {
547- if (totalMomentum >= mPionTPCMomBins [i] && totalMomentum < mPionTPCMomBins [i + 1 ] &&
548- tpcNSigPi < mPionTPCNSigCuts [i] && tpcNSigPr > tpcNSigmaVetoThreshold) {
549- tpcPassed = true ;
550- break ;
580+ // No TOF available (or useTPCOnlyPID == true)
581+ if (totalMomentum < minPionMomentum && tpcNSigPi < static_cast <float >(maxTPCNSigmaPion)) {
582+ // ── Part 2: low-momentum, no TOF → TPC-only regardless of configurable ──
583+ tpcPassed = true ;
584+ tofPassed = true ;
585+ } else {
586+ tofPassed = true ;
587+ if (track.tpcNSigmaPi () < minTPCNSigmaPion)
588+ return false ;
589+ for (int i = 0 ; i < nTPCBins - 1 ; ++i) {
590+ if (totalMomentum >= mPionTPCMomBins [i] && totalMomentum < mPionTPCMomBins [i + 1 ] &&
591+ tpcNSigPi < mPionTPCNSigCuts [i] && tpcNSigPr > tpcNSigmaVetoThreshold) {
592+ tpcPassed = true ;
593+ break ;
594+ }
551595 }
552596 }
553597 }
@@ -961,7 +1005,7 @@ struct DeltaAnalysis {
9611005 constexpr float kGenCentrality = 1 .f ;
9621006
9631007 for (auto const & collision : collisions) {
964- if (!collision. sel8 () || std::abs ( collision. posZ ()) > cfgCutVertex )
1008+ if (!passesEventSelection ( collision) )
9651009 continue ;
9661010 const float centrality = getCentrality (collision);
9671011 histos.fill (HIST (" Event/hNcontributor" ), collision.numContrib ());
0 commit comments