Skip to content

Commit 1122111

Browse files
committed
Add TruthOnly CF histograms
1 parent e144b37 commit 1122111

File tree

1 file changed

+89
-4
lines changed

1 file changed

+89
-4
lines changed

PWGEM/PhotonMeson/Tasks/photonhbt.cxx

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,8 @@ struct photonhbt {
249249
Configurable<float> cfgMCMaxQinv{"cfgMCMaxQinv", 0.3f, "max q_{inv}^{true} for MC truth efficiency pair loop (GeV/c); <=0 = no cut"};
250250
Configurable<float> cfgMCMinKt{"cfgMCMinKt", 0.0f, "min k_{T}^{true} for MC truth efficiency pair loop (GeV/c); <=0 = no cut"};
251251
Configurable<float> cfgMCMaxKt{"cfgMCMaxKt", 0.7f, "max k_{T}^{true} for MC truth efficiency pair loop (GeV/c); <=0 = no cut"};
252+
Configurable<bool> cfgDoTruthMix{"cfgDoTruthMix", false, "enable truth-level event mixing for baseline CF"};
253+
Configurable<int> cfgTruthMixDepth{"cfgTruthMixDepth", 10, "depth of truth-level mixing pool"};
252254
} mctruth;
253255

254256
struct : ConfigurableGroup {
@@ -342,6 +344,7 @@ struct photonhbt {
342344
emh2 = nullptr;
343345
mapMixedEventIdToGlobalBC.clear();
344346
usedPhotonIdsPerCol.clear();
347+
truthGammaPool.clear();
345348
}
346349

347350
HistogramRegistry fRegistry{"output", {}, OutputObjHandlingPolicy::AnalysisObject, false, false};
@@ -524,6 +527,14 @@ struct photonhbt {
524527
bool valid = true;
525528
};
526529

530+
struct TruthGamma {
531+
int id = -1, posId = -1, negId = -1;
532+
float eta = 0.f, phi = 0.f, pt = 0.f, rTrue = -1.f, legDRtrue = -1.f;
533+
};
534+
535+
std::map<std::tuple<int, int, int, int>, std::deque<std::vector<TruthGamma>>> truthGammaPool;
536+
537+
527538
void addSinglePhotonQAHistogramsForStep(const std::string& path)
528539
{
529540
fRegistryPairQA.add((path + "hPt").c_str(), "p_{T};p_{T} (GeV/c);counts", kTH1D, {axisPt}, true);
@@ -1105,6 +1116,21 @@ struct photonhbt {
11051116

11061117
const AxisSpec axQinvMC{60, 0.f, 0.3f, "q_{inv}^{true} (GeV/c)"};
11071118

1119+
// Same-event truth CF
1120+
fRegistryMC.add("MC/TruthCF/hQinvVsKt_same",
1121+
"truth-level same-event CF;k_{T} (GeV/c);q_{inv}^{true} (GeV/c)",
1122+
kTH2D, {axisKt, axQinvMC}, true);
1123+
fRegistryMC.add("MC/TruthCF/hDEtaDPhi_same",
1124+
"truth-level same-event #Delta#eta vs #Delta#phi",
1125+
kTH2D, {axisDeltaEta, axisDeltaPhi}, true);
1126+
// Mixed-event truth CF
1127+
fRegistryMC.add("MC/TruthCF/hQinvVsKt_mix",
1128+
"truth-level mixed-event CF;k_{T} (GeV/c);q_{inv}^{true} (GeV/c)",
1129+
kTH2D, {axisKt, axQinvMC}, true);
1130+
fRegistryMC.add("MC/TruthCF/hDEtaDPhi_mix",
1131+
"truth-level mixed-event #Delta#eta vs #Delta#phi",
1132+
kTH2D, {axisDeltaEta, axisDeltaPhi}, true);
1133+
11081134
fRegistryMC.add("MC/TruthAO2D/hSparse_DEtaDPhi_qinv_truthConverted",
11091135
"true converted pairs, denominator;"
11101136
"#Delta#eta_{#gamma#gamma};#Delta#phi_{#gamma#gamma} (rad);q_{inv}^{true} (GeV/c)",
@@ -1874,10 +1900,6 @@ struct photonhbt {
18741900
info.passesCut = info.passesCut || passes;
18751901
}
18761902

1877-
struct TruthGamma {
1878-
int id = -1, posId = -1, negId = -1;
1879-
float eta = 0.f, phi = 0.f, pt = 0.f, rTrue = -1.f, legDRtrue = -1.f;
1880-
};
18811903
std::vector<TruthGamma> trueGammas;
18821904
trueGammas.reserve(32);
18831905

@@ -2049,6 +2071,69 @@ struct photonhbt {
20492071
}
20502072
}
20512073
}
2074+
// ─── Truth-level same-event pairs ────────────────────────────────────────
2075+
if (mctruth.cfgDoTruthMix.value) {
2076+
for (size_t i = 0; i < trueGammas.size(); ++i) {
2077+
for (size_t j = i + 1; j < trueGammas.size(); ++j) {
2078+
const auto& g1 = trueGammas[i];
2079+
const auto& g2 = trueGammas[j];
2080+
if (!passAsymmetryCut(g1.pt, g2.pt))
2081+
continue;
2082+
const float deta = g1.eta - g2.eta;
2083+
const float dphi = wrapPhi(g1.phi - g2.phi);
2084+
const float px1 = g1.pt * std::cos(g1.phi), py1 = g1.pt * std::sin(g1.phi);
2085+
const float px2 = g2.pt * std::cos(g2.phi), py2 = g2.pt * std::sin(g2.phi);
2086+
const float kt = 0.5f * std::sqrt((px1 + px2) * (px1 + px2) + (py1 + py2) * (py1 + py2));
2087+
const float e1 = g1.pt * std::cosh(g1.eta), e2 = g2.pt * std::cosh(g2.eta);
2088+
const float dot = e1 * e2 - (px1 * px2 + py1 * py2 + g1.pt * std::sinh(g1.eta) * g2.pt * std::sinh(g2.eta));
2089+
const float qinv_true = std::sqrt(std::max(0.f, 2.f * dot));
2090+
fRegistryMC.fill(HIST("MC/TruthCF/hQinvVsKt_same"), kt, qinv_true);
2091+
fRegistryMC.fill(HIST("MC/TruthCF/hDEtaDPhi_same"), deta, dphi);
2092+
}
2093+
}
2094+
2095+
// ─── Truth-level mixed-event pairs ─────────────────────────────────────
2096+
const float cent[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()};
2097+
const float centForBin = cent[mixing.cfgCentEstimator.value];
2098+
const std::array<float, 7> epArr = {collision.ep2ft0m(), collision.ep2ft0a(), collision.ep2ft0c(),
2099+
collision.ep2fv0a(), collision.ep2btot(), collision.ep2bpos(), collision.ep2bneg()};
2100+
const float ep2 = epArr[mixing.cfgEP2EstimatorForMix.value];
2101+
const float occupancy = (mixing.cfgOccupancyEstimator.value == 1)
2102+
? static_cast<float>(collision.trackOccupancyInTimeRange())
2103+
: collision.ft0cOccupancyInTimeRange();
2104+
auto keyBin = std::make_tuple(binOf(ztxBinEdges, collision.posZ()),
2105+
binOf(centBinEdges, centForBin),
2106+
binOf(epBinEgdes, ep2),
2107+
binOf(occBinEdges, occupancy));
2108+
2109+
if (truthGammaPool.count(keyBin)) {
2110+
for (const auto& poolEvent : truthGammaPool[keyBin]) {
2111+
for (const auto& g1 : trueGammas) {
2112+
for (const auto& g2 : poolEvent) {
2113+
if (!passAsymmetryCut(g1.pt, g2.pt))
2114+
continue;
2115+
const float deta = g1.eta - g2.eta;
2116+
const float dphi = wrapPhi(g1.phi - g2.phi);
2117+
const float px1 = g1.pt * std::cos(g1.phi), py1 = g1.pt * std::sin(g1.phi);
2118+
const float px2 = g2.pt * std::cos(g2.phi), py2 = g2.pt * std::sin(g2.phi);
2119+
const float kt = 0.5f * std::sqrt((px1 + px2) * (px1 + px2) + (py1 + py2) * (py1 + py2));
2120+
const float e1 = g1.pt * std::cosh(g1.eta), e2 = g2.pt * std::cosh(g2.eta);
2121+
const float dot = e1 * e2 - (px1 * px2 + py1 * py2 + g1.pt * std::sinh(g1.eta) * g2.pt * std::sinh(g2.eta));
2122+
const float qinv_true = std::sqrt(std::max(0.f, 2.f * dot));
2123+
fRegistryMC.fill(HIST("MC/TruthCF/hQinvVsKt_mix"), kt, qinv_true);
2124+
fRegistryMC.fill(HIST("MC/TruthCF/hDEtaDPhi_mix"), deta, dphi);
2125+
}
2126+
}
2127+
}
2128+
}
2129+
2130+
if (!trueGammas.empty()) {
2131+
auto& poolBin = truthGammaPool[keyBin];
2132+
poolBin.push_back(trueGammas);
2133+
if (static_cast<int>(poolBin.size()) > mctruth.cfgTruthMixDepth.value)
2134+
poolBin.pop_front();
2135+
}
2136+
} // end cfgDoTruthMix
20522137
}
20532138
}
20542139

0 commit comments

Comments
 (0)