Skip to content

Commit b2754cc

Browse files
[PWGLF] added the constant shift for the TOF species and also pt dependent DC… (#18143)
1 parent d5b6d3e commit b2754cc

1 file changed

Lines changed: 42 additions & 30 deletions

File tree

‎PWGLF/Tasks/Resonances/deltaAnalysis.cxx‎

Lines changed: 42 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -94,13 +94,15 @@ struct DeltaAnalysis {
9494
Configurable<bool> cfgRequireRecoINELgt0{"cfgRequireRecoINELgt0", true, "Require reconstructed INEL>0 event class (at least one PV track in |eta|<1)"};
9595
Configurable<bool> cfgUseNoSameBunchPileupCut{"cfgUseNoSameBunchPileupCut", false, "Apply kNoSameBunchPileup event selection"};
9696
Configurable<bool> cfgUseGoodZvtxFT0vsPVCut{"cfgUseGoodZvtxFT0vsPVCut", false, "Apply kIsGoodZvtxFT0vsPV event selection"};
97+
Configurable<bool> cfgUseGoodITSLayersAll{"cfgUseGoodITSLayersAll", false, "Apply kIsGoodITSLayersAll event selection"};
9798
Configurable<bool> applyOccupancyInTimeRangeCut{"applyOccupancyInTimeRangeCut", false, "Apply occupancy-in-time-range cut"};
9899
Configurable<int> cfgOccupancyMin{"cfgOccupancyMin", 0, "Minimum track occupancy in time range"};
99100
Configurable<int> cfgOccupancyMax{"cfgOccupancyMax", 9999, "Maximum track occupancy in time range"};
100101
Configurable<int> cfgCentralityEstimator{"cfgCentralityEstimator", 0, "Centrality estimator: 0=FT0M 1=FT0A 2=FT0C 3=FV0A 4=NTPV"};
101102
Configurable<float> cfgCentMin{"cfgCentMin", 0.f, "Minimum centrality percentile"};
102103
Configurable<float> cfgCentMax{"cfgCentMax", 100.f, "Maximum centrality percentile"};
103104
Configurable<bool> cfgUseMCTruthCentrality{"cfgUseMCTruthCentrality", false, "Use MC truth centrality for generated Delta histograms"};
105+
Configurable<bool> cfgApplyMCTruthINELgt0{"cfgApplyMCTruthINELgt0", true, "Apply truth-level INEL>0 selection to MC generated events"};
104106
} evSel;
105107

106108
struct : ConfigurableGroup {
@@ -125,7 +127,7 @@ struct DeltaAnalysis {
125127
Configurable<bool> applyTPCChi2NClCut{"applyTPCChi2NClCut", true, "Enable/disable maximum TPC chi2/NCl cut"};
126128
Configurable<bool> applyITSChi2NClCut{"applyITSChi2NClCut", true, "Enable/disable maximum ITS chi2/NCl cut"};
127129
Configurable<bool> requirePrimaryTrack{"requirePrimaryTrack", true, "Require isPrimaryTrack flag"};
128-
Configurable<bool> requireGlobalTrackNoDCA{"requireGlobalTrackNoDCA", true, "Require isGlobalTrackWoDCA flag"};
130+
Configurable<bool> requireGlobalTrack{"requireGlobalTrack", true, "Require global track"};
129131
Configurable<bool> requirePVContributor{"requirePVContributor", true, "Require PV-contributor flag"};
130132
} trackCuts;
131133

@@ -135,6 +137,10 @@ struct DeltaAnalysis {
135137
Configurable<std::vector<float>> protonMaxDCAxyPerPtBin{"protonMaxDCAxyPerPtBin", {0.10f, 0.08f, 0.05f, 0.05f}, "Max |DCAxy| for proton per pT bin [cm]"};
136138
Configurable<std::vector<float>> pionDCAPtBinEdges{"pionDCAPtBinEdges", {0.0f, 0.5f, 1.0f, 2.0f, 1000.f}, "Pion pT bin edges for DCAxy cut [GeV/c]"};
137139
Configurable<std::vector<float>> pionMaxDCAxyPerPtBin{"pionMaxDCAxyPerPtBin", {0.20f, 0.15f, 0.10f, 0.08f}, "Max |DCAxy| for pion per pT bin [cm]"};
140+
Configurable<bool> isApplyPtDepDCAxyCut{"isApplyPtDepDCAxyCut", false, "Use continuous pT-dependent DCAxy cut"};
141+
Configurable<float> dcaXYConst{"dcaXYConst", 0.0105f, "Constant term of pT-dependent DCAxy cut [cm]"};
142+
Configurable<float> dcaXYPtCoeff{"dcaXYPtCoeff", 0.035f, "pT-dependent coefficient of DCAxy cut [cm]"};
143+
Configurable<float> dcaXYPtExponent{"dcaXYPtExponent", 1.1f, "pT exponent of DCAxy cut"};
138144
} dcaCuts;
139145

140146
struct : ConfigurableGroup {
@@ -155,6 +161,7 @@ struct DeltaAnalysis {
155161
Configurable<std::vector<float>> protonTPCNSigmaCutPerBin{"protonTPCNSigmaCutPerBin", {5.f, 3.5f, 2.5f}, "Maximum TPC nSigma for proton per momentum bin"};
156162
Configurable<std::vector<float>> protonTOFPIDMomentumBins{"protonTOFPIDMomentumBins", {0.f, 999.f}, "Proton TOF PID momentum bin edges [GeV/c]"};
157163
Configurable<std::vector<float>> protonTOFNSigmaCutPerBin{"protonTOFNSigmaCutPerBin", {3.0f}, "Maximum TOF nSigma for proton per momentum bin"};
164+
Configurable<float> shiftInNsigmaTOFProton{"shiftInNsigmaTOFProton", 0.0f, "Shift applied to proton TOF nSigma"};
158165
} protonPID;
159166

160167
struct : ConfigurableGroup {
@@ -169,6 +176,7 @@ struct DeltaAnalysis {
169176
Configurable<std::vector<float>> pionTPCNSigmaCutPerBin{"pionTPCNSigmaCutPerBin", {5.f, 3.5f, 2.5f}, "Maximum TPC nSigma for pion per momentum bin"};
170177
Configurable<std::vector<float>> pionTOFPIDMomentumBins{"pionTOFPIDMomentumBins", {0.f, 999.f}, "Pion TOF PID momentum bin edges [GeV/c]"};
171178
Configurable<std::vector<float>> pionTOFNSigmaCutPerBin{"pionTOFNSigmaCutPerBin", {3.0f}, "Maximum TOF nSigma for pion per momentum bin"};
179+
Configurable<float> shiftInNsigmaTOFPion{"shiftInNsigmaTOFPion", 0.0f, "Shift applied to pion TOF nSigma"};
172180
} pionPID;
173181

174182
struct : ConfigurableGroup {
@@ -432,10 +440,7 @@ struct DeltaAnalysis {
432440
histos.add("MCRecoEvent/centralitydistribution", "Centrality distribution (MC);vCentFT0M;Entries", kTH1F, {centAxis});
433441
}
434442

435-
// ── MC reconstructed event mixing: histograms (gated by the dedicated MC mixing switch,
436-
// independent from doprocessMC / doprocessMixedEvent). Mirrors the DATA EM histograms
437-
// one-to-one but lives under its own AnalysisMCReco / THnSparseMCReco keys so downstream
438-
// scripts can never confuse DATA-EM with MCReco-EM. ─────────────────────────────────────
443+
// ── MC reconstructed event mixing: histograms (gated by the dedicated MC mixing switch)
439444
if (mixingCfg.enableMCEventMixing) {
440445
histos.add("AnalysisMCReco/hDeltaPlusPlusInvMassEM", "#Delta^{++} invariant mass - MC reconstructed event mixing", kTH2F, {ptAxis, massAxis});
441446
histos.add("AnalysisMCReco/hAntiDeltaPlusPlusInvMassEM", "#bar{#Delta}^{++} invariant mass - MC reconstructed event mixing", kTH2F, {ptAxis, massAxis});
@@ -447,7 +452,6 @@ struct DeltaAnalysis {
447452
histos.add("THnSparseMCReco/hDeltaZeroEM", "THnSparse #Delta^{0} MC reconstructed event mixing", kTHnSparseF, {massAxis, ptAxis, centAxis, rapAxis});
448453
histos.add("THnSparseMCReco/hAntiDeltaZeroEM", "THnSparse #bar{#Delta}^{0} MC reconstructed event mixing", kTHnSparseF, {massAxis, ptAxis, centAxis, rapAxis});
449454

450-
// Minimal debug QA: verifies MC mixing actually ran (non-zero when enabled and MC data flows through it).
451455
histos.add("QAMC/EventMixing/hMixedEventPairs", "Number of MC mixed-event collision pairs processed", kTH1F, {{1, 0.5f, 1.5f}});
452456
histos.add("QAMC/EventMixing/hMixedEventPairsByCentrality", "MC mixed-event collision pairs vs centrality", kTH1F, {centAxis});
453457
}
@@ -472,9 +476,6 @@ struct DeltaAnalysis {
472476
histos.add("MCGenQA/hGenPionAntiDeltaPlusPlus", "Gen pion from #bar{#Delta}^{++}", kTH1F, {ptAxis});
473477
histos.add("MCGenQA/hGenPionDeltaZero", "Gen pion from #Delta^{0}", kTH1F, {ptAxis});
474478
histos.add("MCGenQA/hGenPionAntiDeltaZero", "Gen pion from #bar{#Delta}^{0}", kTH1F, {ptAxis});
475-
476-
// Generated-Delta cut flow. 0=All generated, 1=producedByGenerator, 2=truth vertex-z,
477-
// 3=truth INEL>0, 4=PDG, 5=rapidity, 6=decay channel, 7=final generated histogram.
478479
histos.add("MCGenQA/hGenDeltaCutFlow", "Generated #Delta cut flow", kTH1F, {{8, -0.5f, 7.5f}});
479480

480481
histos.add("MCGen/GeneratedDelta_EventAccepted/hDeltaPlusPlusInvMass", "#Delta^{++} generated, event-accepted", kTH2F, {ptAxis, massAxis});
@@ -497,9 +498,6 @@ struct DeltaAnalysis {
497498
}
498499

499500
// ── Event-level cut-flow (QA-only) histograms ───────────────────────────────────────────
500-
// These are pure bookkeeping: they record how many events survive each existing selection
501-
// step (already implemented in passesEventSelectionImpl<Tag>(), isTruthInelGt0(), and
502-
// processEventFactor()) and do not themselves apply, add, or alter any selection.
503501
{
504502
histos.add("CutFlow/Data/hEventCutFlow", "Data event cut flow", kTH1F, {{9, -0.5f, 8.5f}});
505503
auto hDataCutFlow = histos.get<TH1>(HIST("CutFlow/Data/hEventCutFlow"));
@@ -622,8 +620,6 @@ struct DeltaAnalysis {
622620
return collision.multNTracksPVeta1() > 0;
623621
}
624622

625-
// Truth-level charged-primary identification, used only to build the truth-level INEL>0 event
626-
// class (isTruthInelGt0 below).
627623
template <typename McParticleType>
628624
bool isChargedPrimaryMC(McParticleType const& mcPart)
629625
{
@@ -637,8 +633,6 @@ struct DeltaAnalysis {
637633
return std::abs(pdgParticle->Charge()) > MinAbsCharge;
638634
}
639635

640-
// Truth-level analogue of isRecoInelGt0() above - at least one charged primary within
641-
// |eta| < 1 among the generated particles of a given MC collision.
642636
template <typename McParticleTableType>
643637
bool isTruthInelGt0(McParticleTableType const& mcParticlesInCollision)
644638
{
@@ -710,6 +704,11 @@ struct DeltaAnalysis {
710704
}
711705
fillEventCutFlowBin<Tag>(7.f); // GoodZvtxFT0vsPV
712706

707+
if (evSel.cfgUseGoodITSLayersAll &&
708+
!collision.selection_bit(o2::aod::evsel::kIsGoodITSLayersAll)) {
709+
return false;
710+
}
711+
713712
fillEventCutFlowBin<Tag>(8.f); // Final accepted event
714713
return true;
715714
}
@@ -755,7 +754,7 @@ struct DeltaAnalysis {
755754
if (trackCuts.requirePrimaryTrack && !track.isPrimaryTrack()) {
756755
return false;
757756
}
758-
if (trackCuts.requireGlobalTrackNoDCA && !track.isGlobalTrackWoDCA()) {
757+
if (trackCuts.requireGlobalTrack && !track.isGlobalTrack()) {
759758
return false;
760759
}
761760
if (trackCuts.requirePVContributor && !track.isPVContributor()) {
@@ -767,6 +766,14 @@ struct DeltaAnalysis {
767766
template <typename TrackType>
768767
bool passesProtonDCASelection(TrackType const& track)
769768
{
769+
if (dcaCuts.isApplyPtDepDCAxyCut) {
770+
const float dcaConst = dcaCuts.dcaXYConst;
771+
const float dcaCoeff = dcaCuts.dcaXYPtCoeff;
772+
const float dcaExp = dcaCuts.dcaXYPtExponent;
773+
const float maxDCAxy = dcaConst + dcaCoeff / std::pow(track.pt(), dcaExp);
774+
return (std::abs(track.dcaXY()) < maxDCAxy) && (std::abs(track.dcaZ()) < dcaCuts.cfgCutDCAz);
775+
}
776+
770777
const int nBins = static_cast<int>(mProtonDCAPtEdges.size()) - 1;
771778
const float pt = track.pt();
772779
bool passed = false;
@@ -783,6 +790,14 @@ struct DeltaAnalysis {
783790
template <typename TrackType>
784791
bool passesPionDCASelection(TrackType const& track)
785792
{
793+
if (dcaCuts.isApplyPtDepDCAxyCut) {
794+
const float dcaConst = dcaCuts.dcaXYConst;
795+
const float dcaCoeff = dcaCuts.dcaXYPtCoeff;
796+
const float dcaExp = dcaCuts.dcaXYPtExponent;
797+
const float maxDCAxy = dcaConst + dcaCoeff / std::pow(track.pt(), dcaExp);
798+
return (std::abs(track.dcaXY()) < maxDCAxy) && (std::abs(track.dcaZ()) < dcaCuts.cfgCutDCAz);
799+
}
800+
786801
const int nBins = static_cast<int>(mPionDCAPtEdges.size()) - 1;
787802
const float pt = track.pt();
788803
bool passed = false;
@@ -831,7 +846,8 @@ struct DeltaAnalysis {
831846
}
832847

833848
// Circular mode: joint TPC+TOF nSigma radius.
834-
const float combinedNSigPr = tpcNSigPr * tpcNSigPr + tofNSigPr * tofNSigPr;
849+
const float shiftedTofNSigPr = track.tofNSigmaPr() - static_cast<float>(protonPID.shiftInNsigmaTOFProton);
850+
const float combinedNSigPr = tpcNSigPr * tpcNSigPr + shiftedTofNSigPr * shiftedTofNSigPr;
835851
const float combinedNSigPi = tpcNSigPi * tpcNSigPi + tofNSigPi * tofNSigPi;
836852
const auto circularCutSq = static_cast<float>(protonPID.combinedNSigmaCutProton * protonPID.combinedNSigmaCutProton);
837853
const float circularVetoCutSq = pidShared.tpcNSigmaVetoThreshold * pidShared.tpcNSigmaVetoThreshold +
@@ -888,7 +904,8 @@ struct DeltaAnalysis {
888904
}
889905

890906
// Circular mode: joint TPC+TOF nSigma radius.
891-
const float combinedNSigPi = tpcNSigPi * tpcNSigPi + tofNSigPi * tofNSigPi;
907+
const float shiftedTofNSigPi = track.tofNSigmaPi() - static_cast<float>(pionPID.shiftInNsigmaTOFPion);
908+
const float combinedNSigPi = tpcNSigPi * tpcNSigPi + shiftedTofNSigPi * shiftedTofNSigPi;
892909
const float combinedNSigPr = tpcNSigPr * tpcNSigPr + tofNSigPr * tofNSigPr;
893910
const auto circularCutSq = static_cast<float>(pionPID.combinedNSigmaCutPion * pionPID.combinedNSigmaCutPion);
894911
const float circularVetoCutSq = pidShared.tpcNSigmaVetoThreshold * pidShared.tpcNSigmaVetoThreshold +
@@ -928,7 +945,7 @@ struct DeltaAnalysis {
928945
histos.fill(HIST("QAafter/Proton/tpcCrossedRowsVsPt"), pt, track.tpcNClsCrossedRows());
929946
histos.fill(HIST("QAafter/Proton/tpcClustersFoundVsPt"), pt, track.tpcNClsFound());
930947
if (!pidShared.useTPCOnlyPID && track.hasTOF()) {
931-
const float tofNSigPr = track.tofNSigmaPr();
948+
const float tofNSigPr = track.tofNSigmaPr() - static_cast<float>(protonPID.shiftInNsigmaTOFProton);
932949
histos.fill(HIST("QAafter/Proton/tofNSigmaVsMomentum"), totalMomentum, tofNSigPr);
933950
histos.fill(HIST("QAafter/Proton/tofNSigmaVsPt"), pt, tofNSigPr);
934951
histos.fill(HIST("QAafter/Proton/tofNSigmaVsCentrality"), centralityPercent, tofNSigPr);
@@ -954,7 +971,7 @@ struct DeltaAnalysis {
954971
histos.fill(HIST("QAafter/Pion/tpcCrossedRowsVsPt"), pt, track.tpcNClsCrossedRows());
955972
histos.fill(HIST("QAafter/Pion/tpcClustersFoundVsPt"), pt, track.tpcNClsFound());
956973
if (!pidShared.useTPCOnlyPID && track.hasTOF()) {
957-
const float tofNSigPi = track.tofNSigmaPi();
974+
const float tofNSigPi = track.tofNSigmaPi() - static_cast<float>(pionPID.shiftInNsigmaTOFPion);
958975
histos.fill(HIST("QAafter/Pion/tofNSigmaVsMomentum"), totalMomentum, tofNSigPi);
959976
histos.fill(HIST("QAafter/Pion/tofNSigmaVsPt"), pt, tofNSigPi);
960977
histos.fill(HIST("QAafter/Pion/tofNSigmaVsCentrality"), centralityPercent, tofNSigPi);
@@ -980,7 +997,7 @@ struct DeltaAnalysis {
980997
histos.fill(HIST("QAMC/Proton/tpcCrossedRowsVsPt"), pt, track.tpcNClsCrossedRows());
981998
histos.fill(HIST("QAMC/Proton/tpcClustersFoundVsPt"), pt, track.tpcNClsFound());
982999
if (!pidShared.useTPCOnlyPID && track.hasTOF()) {
983-
const float tofNSigPr = track.tofNSigmaPr();
1000+
const float tofNSigPr = track.tofNSigmaPr() - static_cast<float>(protonPID.shiftInNsigmaTOFProton);
9841001
histos.fill(HIST("QAMC/Proton/tofNSigmaVsMomentum"), totalMomentum, tofNSigPr);
9851002
histos.fill(HIST("QAMC/Proton/tofNSigmaVsPt"), pt, tofNSigPr);
9861003
histos.fill(HIST("QAMC/Proton/tofNSigmaVsCentrality"), centralityPercent, tofNSigPr);
@@ -1006,7 +1023,7 @@ struct DeltaAnalysis {
10061023
histos.fill(HIST("QAMC/Pion/tpcCrossedRowsVsPt"), pt, track.tpcNClsCrossedRows());
10071024
histos.fill(HIST("QAMC/Pion/tpcClustersFoundVsPt"), pt, track.tpcNClsFound());
10081025
if (!pidShared.useTPCOnlyPID && track.hasTOF()) {
1009-
const float tofNSigPi = track.tofNSigmaPi();
1026+
const float tofNSigPi = track.tofNSigmaPi() - static_cast<float>(pionPID.shiftInNsigmaTOFPion);
10101027
histos.fill(HIST("QAMC/Pion/tofNSigmaVsMomentum"), totalMomentum, tofNSigPi);
10111028
histos.fill(HIST("QAMC/Pion/tofNSigmaVsPt"), pt, tofNSigPi);
10121029
histos.fill(HIST("QAMC/Pion/tofNSigmaVsCentrality"), centralityPercent, tofNSigPi);
@@ -1889,7 +1906,7 @@ struct DeltaAnalysis {
18891906
histos.fill(HIST("EfficiencyQA/hGeneratedEventCutFlow"), 1.f); // |Vz| accepted
18901907

18911908
const bool truthInelGt0 = isTruthInelGt0(mcParticles);
1892-
if (evSel.cfgRequireRecoINELgt0 && !truthInelGt0) {
1909+
if (evSel.cfgApplyMCTruthINELgt0 && !truthInelGt0) {
18931910
return;
18941911
}
18951912
histos.fill(HIST("CutFlow/MCGen/hEventCutFlow"), 2.f); // Truth INEL>0
@@ -1898,8 +1915,6 @@ struct DeltaAnalysis {
18981915
histos.fill(HIST("CutFlow/MCGen/hEventCutFlow"), 4.f); // Final generated event
18991916
histos.fill(HIST("EfficiencyQA/hGeneratedEventCutFlow"), 3.f); // Final generated event
19001917

1901-
// ── MODIFIED BLOCK (per user request): centrality-source switch for generated Delta ────
1902-
// Added: evSel.cfgUseMCTruthCentrality (see Configurable added in evSel group above).
19031918
bool hasAcceptedReco = false;
19041919
float genCentrality = mcCollision.centFT0M();
19051920

@@ -2062,7 +2077,7 @@ struct DeltaAnalysis {
20622077
histos.fill(HIST("CutFlow/EventFactor/hEventAcceptedCutFlow"), 1.f); // |Vz| < cfgCutVertex
20632078

20642079
auto mcPartsThisColl = mcParticles.sliceBy(perMcCollisionDelta, mcCollision.globalIndex());
2065-
if (evSel.cfgRequireRecoINELgt0 && !isTruthInelGt0(mcPartsThisColl)) {
2080+
if (evSel.cfgApplyMCTruthINELgt0 && !isTruthInelGt0(mcPartsThisColl)) {
20662081
continue;
20672082
}
20682083
histos.fill(HIST("CutFlow/EventFactor/hEventAcceptedCutFlow"), 2.f); // Truth INEL>0
@@ -2083,10 +2098,7 @@ struct DeltaAnalysis {
20832098
if (hasAcceptedReco) {
20842099
histos.fill(HIST("CutFlow/EventFactor/hEventAcceptedCutFlow"), 4.f); // Associated reco collision passes event selection
20852100
histos.fill(HIST("CutFlow/EventFactor/hEventAcceptedCutFlow"), 5.f); // Final EventAccepted
2086-
// Truth-binned: denominator for event_loss = hEventsGenAccepted / hEventsGenAll (unchanged).
20872101
histos.fill(HIST("EventFactor/hEventsGenAccepted"), truthCentrality);
2088-
// NEW - reco-binned: numerator for event_splitting = hEventsGenAcceptedReco / hRecoEvents,
2089-
// now on the same (reconstructed) centrality axis as hRecoEvents.
20902102
histos.fill(HIST("EventFactor/hEventsGenAcceptedReco"), itCent->second);
20912103
}
20922104
}

0 commit comments

Comments
 (0)