Skip to content

Commit 2d5855c

Browse files
committed
Update hStrangeCorrelation.cxx
1 parent ede5910 commit 2d5855c

1 file changed

Lines changed: 80 additions & 0 deletions

File tree

PWGLF/Tasks/Strangeness/hStrangeCorrelation.cxx

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -311,6 +311,19 @@ struct HStrangeCorrelation {
311311
ConfigurableAxis axisDaughterDeltaEta{"axisDaughterDeltaEta", {100, -0.2f, 0.2f}, "trigger-daughter delta eta"};
312312
ConfigurableAxis axisDaughterDeltaPhi{"axisDaughterDeltaPhi", {120, -0.3f, 0.3f}, "trigger-daughter delta phi"};
313313
ConfigurableAxis axisDecayRadius{"axisDecayRadius", {100, 0.0f, 200.0f}, "generated K0 decay radius (cm)"};
314+
// The following mirror the isValidTrigger() cuts applied by hStrangeCorrelationFilter.cxx
315+
// when building the TriggerTracks table. They must be kept in sync by hand with whatever
316+
// values are configured for that (separate) filter task, since this diagnostic cannot read
317+
// them directly: it only sees the already-filtered TriggerTracks table, not why a given
318+
// best-collision track failed to enter it.
319+
Configurable<float> triggerTracksEtaMin{"triggerTracksEtaMin", -0.8f, "must match triggerEtaMin in hStrangeCorrelationFilter.cxx"};
320+
Configurable<float> triggerTracksEtaMax{"triggerTracksEtaMax", 0.8f, "must match triggerEtaMax in hStrangeCorrelationFilter.cxx"};
321+
Configurable<float> triggerTracksPtMin{"triggerTracksPtMin", 3.0f, "must match triggerPtCutMin in hStrangeCorrelationFilter.cxx"};
322+
Configurable<float> triggerTracksPtMax{"triggerTracksPtMax", 20.0f, "must match triggerPtCutMax in hStrangeCorrelationFilter.cxx"};
323+
Configurable<int> triggerTracksMinCrossedRows{"triggerTracksMinCrossedRows", 70, "must match minTPCNCrossedRows in hStrangeCorrelationFilter.cxx"};
324+
Configurable<bool> triggerTracksRequireITS{"triggerTracksRequireITS", true, "must match triggerRequireITS in hStrangeCorrelationFilter.cxx"};
325+
Configurable<int> triggerTracksMaxSharedClusters{"triggerTracksMaxSharedClusters", 200, "must match triggerMaxTPCSharedClusters in hStrangeCorrelationFilter.cxx"};
326+
Configurable<bool> triggerTracksRequireLayer0{"triggerTracksRequireLayer0", false, "must match triggerRequireL0 in hStrangeCorrelationFilter.cxx"};
314327
} pairLossK0Configurations;
315328

316329
struct ValidCollision {
@@ -488,6 +501,29 @@ struct HStrangeCorrelation {
488501
bool hasLayer0 = false;
489502
};
490503

504+
// First-failing-condition breakdown for the stage3->4 gate ("Trigger track, best collision"
505+
// -> "Trigger in TriggerTracks"). Order mirrors the early-return order of isValidTrigger()
506+
// in hStrangeCorrelationFilter.cxx exactly, so "first reason to fail" means the same thing here.
507+
enum PairLossTriggerTracksFailureReason : int {
508+
PairLossTriggerTracksPassed = 0,
509+
PairLossTriggerTracksFailEta,
510+
PairLossTriggerTracksFailPt,
511+
PairLossTriggerTracksFailCrossedRows,
512+
PairLossTriggerTracksFailITS,
513+
PairLossTriggerTracksFailSharedClusters,
514+
PairLossTriggerTracksFailLayer0,
515+
PairLossTriggerTracksNReasons
516+
};
517+
518+
static constexpr std::array<std::string_view, PairLossTriggerTracksNReasons> PairLossTriggerTracksFailureNames = {
519+
"Passed all cuts (in TriggerTracks)",
520+
"Failed eta window",
521+
"Failed pT window",
522+
"Failed min TPC crossed rows",
523+
"Failed hasITS requirement",
524+
"Failed max TPC shared clusters",
525+
"Failed ITS layer-0 requirement"};
526+
491527
struct PairLossV0Info {
492528
int64_t globalIndex = -1;
493529
int64_t positiveTrackId = -1;
@@ -564,6 +600,33 @@ struct HStrangeCorrelation {
564600
.hasLayer0 = static_cast<bool>(TESTBIT(track.itsClusterMap(), 0))};
565601
}
566602

603+
// Replicates isValidTrigger() from hStrangeCorrelationFilter.cxx condition-by-condition
604+
// (same early-return order) so that, for a trigger already known to exist in the best
605+
// collision (stage 3), we can tell which single cut is responsible for it not making it
606+
// into the TriggerTracks table (stage 4), instead of only knowing that it failed overall.
607+
int classifyTriggerTracksFailure(PairLossTrackInfo const& info)
608+
{
609+
if (info.eta > pairLossK0Configurations.triggerTracksEtaMax || info.eta < pairLossK0Configurations.triggerTracksEtaMin) {
610+
return PairLossTriggerTracksFailEta;
611+
}
612+
if (info.pt > pairLossK0Configurations.triggerTracksPtMax || info.pt < pairLossK0Configurations.triggerTracksPtMin) {
613+
return PairLossTriggerTracksFailPt;
614+
}
615+
if (info.tpcCrossedRows < pairLossK0Configurations.triggerTracksMinCrossedRows) {
616+
return PairLossTriggerTracksFailCrossedRows;
617+
}
618+
if (info.itsClusters <= 0 && pairLossK0Configurations.triggerTracksRequireITS) {
619+
return PairLossTriggerTracksFailITS;
620+
}
621+
if (info.tpcSharedClusters > pairLossK0Configurations.triggerTracksMaxSharedClusters) {
622+
return PairLossTriggerTracksFailSharedClusters;
623+
}
624+
if (!info.hasLayer0 && pairLossK0Configurations.triggerTracksRequireLayer0) {
625+
return PairLossTriggerTracksFailLayer0;
626+
}
627+
return PairLossTriggerTracksPassed;
628+
}
629+
567630
PairLossDeltaPhiStarInfo calculateMinimumDeltaPhiStar(PairLossTruthTrackInfo const& trigger, PairLossTruthTrackInfo const& daughter, double magneticField, float decayRadiusCm)
568631
{
569632
PairLossDeltaPhiStarInfo result;
@@ -2166,13 +2229,15 @@ struct HStrangeCorrelation {
21662229
const double pairLossRadiusStep = std::max(static_cast<double>(pairLossK0Configurations.radiusStep), 0.001);
21672230
const int pairLossRadiusBins = std::max(1, static_cast<int>(std::ceil((pairLossRadiusMaximum - pairLossRadiusMinimum) / pairLossRadiusStep)));
21682231
const AxisSpec axisPairLossRadiusAtMinimum{pairLossRadiusBins, pairLossRadiusMinimum, pairLossRadiusMaximum, "#it{r}_{min} (m)"};
2232+
const AxisSpec axisPairLossTriggerTracksFailureReason{PairLossTriggerTracksNReasons, -0.5, static_cast<double>(PairLossTriggerTracksNReasons) - 0.5, "TriggerTracks first-failing condition"};
21692233

21702234
histos.add("PairLossK0/Event/hCounter", "K0 pair-loss event counter", kTH1F, {axisPairLossEventStage});
21712235
histos.add("PairLossK0/Event/hNRecoCollisions", "reconstructed collisions per MC collision", kTH1F, {axisPairLossNRecoCollisions});
21722236
histos.add("PairLossK0/Stage/hCounts", "pair-loss diagnostic stage counts", kTH1F, {axisPairLossStage});
21732237
histos.add("PairLossK0/Stage/hCountsFindable", "pair-loss diagnostic stage counts for findable K0", kTH1F, {axisPairLossStage});
21742238
histos.add("PairLossK0/Stage/hPhysics", "stages in h-K0 physics variables", kTHnF, {axisPairLossStage, axisPairLossTruthDeltaPhi, axisPairLossTruthDeltaEta, axisPairLossTruthK0Pt, axisPairLossTruthTriggerPt, axisPairLossFieldSign});
21752239
histos.add("PairLossK0/Stage/hClose", "stages in trigger-daughter close-pair variables", kTHnF, {axisPairLossStage, axisPairLossMinDeltaPhiStar, axisPairLossDaughterDeltaEta, axisPairLossTruthK0Pt, axisPairLossTruthTriggerPt, axisPairLossFieldSign, axisPairLossChargeProduct});
2240+
histos.add("PairLossK0/Stage/hTriggerTracksFailureReason", "first-failing TriggerTracks condition for best-collision triggers, in h-K0 physics variables", kTHnF, {axisPairLossTriggerTracksFailureReason, axisPairLossTruthDeltaPhi, axisPairLossTruthDeltaEta, axisPairLossTruthK0Pt, axisPairLossTruthTriggerPt});
21762241

21772242
histos.add("PairLossK0/State/hFinalObjectStatePhysics", "00/01/10/11 final trigger-K0 object state", kTHnF, {axisPairLossFinalObjectState, axisPairLossTruthDeltaPhi, axisPairLossTruthDeltaEta, axisPairLossTruthK0Pt, axisPairLossTruthTriggerPt, axisPairLossFieldSign});
21782243
histos.add("PairLossK0/State/hFinalObjectStateClose", "00/01/10/11 final trigger-K0 object state in close-pair variables", kTHnF, {axisPairLossFinalObjectState, axisPairLossMinDeltaPhiStar, axisPairLossDaughterDeltaEta, axisPairLossTruthK0Pt, axisPairLossTruthTriggerPt, axisPairLossFieldSign, axisPairLossChargeProduct});
@@ -2226,6 +2291,11 @@ struct HStrangeCorrelation {
22262291
stageCounts->GetYaxis()->SetTitle("Truth-pair entries");
22272292
stageCountsFindable->GetYaxis()->SetTitle("Findable truth-pair entries");
22282293

2294+
auto triggerTracksFailureHistogram = histos.get<THn>(HIST("PairLossK0/Stage/hTriggerTracksFailureReason"));
2295+
for (int i = 0; i < PairLossTriggerTracksNReasons; ++i) {
2296+
triggerTracksFailureHistogram->GetAxis(0)->SetBinLabel(i + 1, PairLossTriggerTracksFailureNames[i].data());
2297+
}
2298+
22292299
const std::array<std::string_view, 4> objectStateLabels = {"00 neither", "01 K0 only", "10 trigger only", "11 both"};
22302300
for (auto const& histogram : {histos.get<THn>(HIST("PairLossK0/State/hFinalObjectStatePhysics")), histos.get<THn>(HIST("PairLossK0/State/hFinalObjectStateClose"))}) {
22312301
for (size_t i = 0; i < objectStateLabels.size(); ++i) {
@@ -4089,6 +4159,16 @@ struct HStrangeCorrelation {
40894159
}
40904160
}
40914161

4162+
// Only meaningful conditional on the trigger already existing in the best collision
4163+
// (stage 3): this asks *why* that already-found, already-correctly-labelled track
4164+
// does or does not make it into the TriggerTracks table (stage 4).
4165+
if (triggerBestCollision) {
4166+
if (auto const* bestCollisionTrigger = bestTrack(tracksBestCollision, truthTrigger.globalIndex)) {
4167+
const int failureReason = classifyTriggerTracksFailure(*bestCollisionTrigger);
4168+
histos.fill(HIST("PairLossK0/Stage/hTriggerTracksFailureReason"), failureReason, truthDeltaPhi, truthDeltaEta, truthK0.pt, truthTrigger.pt);
4169+
}
4170+
}
4171+
40924172
const int finalObjectState = (triggerFinal ? 2 : 0) + (v0Final ? 1 : 0);
40934173
const int trackLevelState = (triggerBestCollision ? 2 : 0) + (bothDaughtersBestCollision ? 1 : 0);
40944174
const int daughterTrackState = (positiveDaughterBestCollision ? 2 : 0) + (negativeDaughterBestCollision ? 1 : 0);

0 commit comments

Comments
 (0)