|
29 | 29 | #include <CCDB/BasicCCDBManager.h> |
30 | 30 | #include <CommonConstants/MathConstants.h> |
31 | 31 | #include <DataFormatsParameters/GRPMagField.h> |
| 32 | +#include <Framework/ASoA.h> |
32 | 33 | #include <Framework/ASoAHelpers.h> |
33 | 34 | #include <Framework/AnalysisDataModel.h> |
34 | 35 | #include <Framework/AnalysisHelpers.h> |
|
47 | 48 | #include <Math/Vector3Dfwd.h> |
48 | 49 | #include <Math/Vector4D.h> // IWYU pragma: keep |
49 | 50 | #include <Math/Vector4Dfwd.h> |
| 51 | +#include <TH1.h> |
50 | 52 | #include <TPDGCode.h> |
51 | 53 | #include <TString.h> |
52 | 54 |
|
@@ -222,6 +224,9 @@ struct Photonhbt { |
222 | 224 | Configurable<float> cfgMaxQinvForQA{"cfgMaxQinvForQA", 0.1f, "fill per-step pair QA histograms only when q_inv < this value"}; |
223 | 225 | Configurable<float> cfgMaxQinvForFullRange{"cfgMaxQinvForFullRange", 0.3f, "fill full-range histograms only when q_inv < this value"}; |
224 | 226 | Configurable<float> cfgMaxQinvForMCQA{"cfgMaxQinvForMCQA", 0.3f, "fill MC truth 1D histograms only when q_inv < this value"}; |
| 227 | + Configurable<int> cfgQaLevel{"cfgQaLevel", 2, "QA: 0 no QA, 1 standard, 2 full diagnostics with leg information etc."}; |
| 228 | + Configurable<bool> cfgFillDRDZSparse{"cfgFillDRDZSparse", true, "book/fill the FullRange |R1-R2|-Deltaz-qinv sparse (large; needs cfgQaLevel>=2)"}; |
| 229 | + Configurable<float> cfgMaxQinvForProcessing{"cfgMaxQinvForProcessing", 0.5, "skip mixed pairs with q_inv above this before building observables"}; |
225 | 230 | } qaflags; |
226 | 231 |
|
227 | 232 | // ─── HBT analysis mode ─────────────────────────────────────────────────────────── |
@@ -507,9 +512,21 @@ struct Photonhbt { |
507 | 512 | // INITS |
508 | 513 | /*************************************************/ |
509 | 514 |
|
| 515 | + |
| 516 | + bool mDoPairQa{true}, mDoSinglePhotonQa{true}, mDoLegPairQA{true}; |
| 517 | + bool mDoPairSepQA{true}, mFillDRDZSparse{true}; |
| 518 | + |
510 | 519 | void init(InitContext& context) |
511 | 520 | { |
512 | 521 | isMC = context.mOptions.get<bool>("processMC"); |
| 522 | + const int qaLevel = qaflags.cfgQaLevel.value; |
| 523 | + mDoPairQa = qaflags.doPairQa.value && qaLevel >= 1; |
| 524 | + mDoSinglePhotonQa = qaflags.doSinglePhotonQa.value && qaLevel >= 1; |
| 525 | + mDoLegPairQA = qaflags.doLegPairQA.value && qaLevel >= 2; |
| 526 | + mDoPairSepQA = pairsep.cfgDoPairSepQA.value && qaLevel >= 2; |
| 527 | + mFillDRDZSparse = qaflags.cfgFillDRDZSparse.value && qaLevel >= 2; |
| 528 | + LOGF(info, "photonhbt QA level %d -> pairQA %d, singlePhotonQA %d, legPairQA %d, pairSep %d, dRdZ sparse %d", |
| 529 | + qaLevel, mDoPairQa, mDoSinglePhotonQa, mDoLegPairQA, mDoPairSepQA, mFillDRDZSparse); |
513 | 530 | mRunNumber = 0; |
514 | 531 | parseBins(mixing.confVtxBins, ztxBinEdges); |
515 | 532 | parseBins(mixing.confCentBins, centBinEdges); |
@@ -676,7 +693,7 @@ struct Photonhbt { |
676 | 693 |
|
677 | 694 | if (isMC) { |
678 | 695 | addPairMCHistograms(); |
679 | | - if (qaflags.doLegPairQA) { |
| 696 | + if (mDoLegPairQA) { |
680 | 697 | addLegPairMCHistograms(); |
681 | 698 | } |
682 | 699 | addTruthMCHistograms(); |
@@ -763,8 +780,10 @@ struct Photonhbt { |
763 | 780 | } |
764 | 781 |
|
765 | 782 | fRegistryPairQA.addClone("Pair/same/QA/", "Pair/mix/QA/"); |
766 | | - addLegPairQAForStep("Pair/same/QA/Before/"); |
767 | | - addLegPairQAForStep("Pair/same/QA/AfterPairCuts/"); |
| 783 | + if (mDoLegPairQA) { |
| 784 | + addLegPairQAForStep("Pair/same/QA/Before/"); |
| 785 | + addLegPairQAForStep("Pair/same/QA/AfterPairCuts/"); |
| 786 | + } |
768 | 787 | } |
769 | 788 |
|
770 | 789 | void addPairMCHistograms() |
@@ -1005,7 +1024,9 @@ struct Photonhbt { |
1005 | 1024 | fRegistryCF.add((path + "hDeltaR3DVsQinv").c_str(), "#Delta r_{3D} vs q_{inv};q_{inv} (GeV/c);#Delta r_{3D} (cm)", kTH2D, {axisQinv, axisDeltaR3D}, true); |
1006 | 1025 | fRegistryCF.add((path + "hQinvVsCent").c_str(), "q_{inv} vs centrality;centrality (%);q_{inv} (GeV/c)", kTH2D, {axisCentQA, axisQinv}, true); |
1007 | 1026 | fRegistryCF.add((path + "hQinvVsOccupancy").c_str(), "q_{inv} vs occupancy;occupancy;q_{inv} (GeV/c)", kTH2D, {axisOccupancy, axisQinv}, true); |
1008 | | - fRegistryCF.add((path + "hSparseDeltaRDeltaZQinv").c_str(), "|R_{1}-R_{2}|,#Delta z,q_{inv}", kTHnSparseD, {axisDeltaR, axisDeltaZ, axisQinv}, true); |
| 1027 | + if (mFillDRDZSparse) { |
| 1028 | + fRegistryCF.add((path + "hSparseDeltaRDeltaZQinv").c_str(), "|R_{1}-R_{2}|,#Delta z,q_{inv}", kTHnSparseD, {axisDeltaR, axisDeltaZ, axisQinv}, true); |
| 1029 | + } |
1009 | 1030 | fRegistryCF.add((path + "hDeltaRCosOAVsQinv").c_str(), "#Delta r/cos(#theta_{op}/2) vs q_{inv};q_{inv} (GeV/c);#Delta r/cos(#theta_{op}/2) (cm)", kTH2D, {axisQinv, {100, 0, 100}}, true); |
1010 | 1031 | } |
1011 | 1032 |
|
@@ -1266,6 +1287,19 @@ struct Photonhbt { |
1266 | 1287 | return s; |
1267 | 1288 | } |
1268 | 1289 |
|
| 1290 | + template <typename TG1, typename TG2> |
| 1291 | + [[nodiscard]] inline bool passFastQinvGate(TG1 const& g1, TG2 const& g2) const |
| 1292 | + { |
| 1293 | + const float qMax = qaflags.cfgMaxQinvForProcessing.value; |
| 1294 | + if (qMax > 1e9f) { // o2-linter: disable=magic-number (skip if non-sensical value is chosen) |
| 1295 | + return true; |
| 1296 | + } |
| 1297 | + const float dEta = g1.eta() - g2.eta(); |
| 1298 | + const float dPhi = RecoDecay::constrainAngle(g1.phi() - g2.phi(), -o2::constants::math::PI); |
| 1299 | + const float q2 = 2.f * g1.pt() * g2.pt() * (std::cosh(dEta) - std::cos(dPhi)); |
| 1300 | + return q2 <= qMax * qMax; |
| 1301 | + } |
| 1302 | + |
1269 | 1303 | [[nodiscard]] inline bool passLegSepCut(PairSep const& s) const |
1270 | 1304 | { |
1271 | 1305 | if (!pairsep.cfgDoLegSepCut.value) { |
@@ -1386,13 +1420,15 @@ struct Photonhbt { |
1386 | 1420 | fRegistryCF.fill(HIST(base) + HIST("hDeltaR3DVsQinv"), obs.qinv, obs.deltaR3D); |
1387 | 1421 | fRegistryCF.fill(HIST(base) + HIST("hQinvVsCent"), cent, obs.qinv); |
1388 | 1422 | fRegistryCF.fill(HIST(base) + HIST("hQinvVsOccupancy"), occupancy, obs.qinv); |
1389 | | - fRegistryCF.fill(HIST(base) + HIST("hSparseDeltaRDeltaZQinv"), obs.deltaR, obs.deltaZ, obs.qinv); |
| 1423 | + if (mFillDRDZSparse) { |
| 1424 | + fRegistryCF.fill(HIST(base) + HIST("hSparseDeltaRDeltaZQinv"), obs.deltaR, obs.deltaZ, obs.qinv); |
| 1425 | + } |
1390 | 1426 | } |
1391 | 1427 |
|
1392 | 1428 | template <int ev_id, bool after_cut = false> |
1393 | 1429 | inline void fillPairSep(PairSep const& s, PairQAObservables const& obs) |
1394 | 1430 | { |
1395 | | - if (!pairsep.cfgDoPairSepQA.value) { |
| 1431 | + if (!mDoPairSepQA) { |
1396 | 1432 | return; |
1397 | 1433 | } |
1398 | 1434 | const float limit = pairsep.cfgPairSepMaxQinv.value; |
@@ -1422,7 +1458,7 @@ struct Photonhbt { |
1422 | 1458 | template <int step_id, typename TPhoton> |
1423 | 1459 | inline void fillSinglePhotonQAStep(TPhoton const& g) |
1424 | 1460 | { |
1425 | | - if (!qaflags.doSinglePhotonQa) { |
| 1461 | + if (!mDoSinglePhotonQa) { |
1426 | 1462 | return; |
1427 | 1463 | } |
1428 | 1464 | constexpr auto base = singlePhotonQAPrefix<step_id>(); |
@@ -1519,7 +1555,7 @@ struct Photonhbt { |
1519 | 1555 | template <int ev_id, int step_id> |
1520 | 1556 | inline void fillPairQAStep(PairQAObservables const& o, float /*cent*/, float /*occupancy*/) |
1521 | 1557 | { |
1522 | | - if (!qaflags.doPairQa) { |
| 1558 | + if (!mDoPairQa) { |
1523 | 1559 | return; |
1524 | 1560 | } |
1525 | 1561 | constexpr auto base = qaPrefix<ev_id, step_id>(); |
@@ -1559,7 +1595,7 @@ struct Photonhbt { |
1559 | 1595 | template <int step_id> |
1560 | 1596 | inline void fillLegPairQAStep(LegPairObservables const& lo, float kt) |
1561 | 1597 | { |
1562 | | - if (!qaflags.doPairQa) { |
| 1598 | + if (!mDoLegPairQA) { |
1563 | 1599 | return; |
1564 | 1600 | } |
1565 | 1601 | constexpr auto base = qaPrefix<0, step_id>(); |
@@ -1948,7 +1984,7 @@ struct Photonhbt { |
1948 | 1984 | auto keyDFCollision = std::make_pair(ndf, collision.globalIndex()); |
1949 | 1985 | auto photons1Coll = photons1.sliceBy(perCollision1, collision.globalIndex()); |
1950 | 1986 | auto photons2Coll = photons2.sliceBy(perCollision2, collision.globalIndex()); |
1951 | | - if (qaflags.doSinglePhotonQa) { |
| 1987 | + if (mDoSinglePhotonQa) { |
1952 | 1988 | for (const auto& g : photons1Coll) { |
1953 | 1989 | if (cut1.template IsSelected<decltype(g), TSubInfos1>(g)) { |
1954 | 1990 | fillSinglePhotonQAStep<0>(g); |
@@ -2039,7 +2075,7 @@ struct Photonhbt { |
2039 | 2075 | addToPool(g1, pwl1); |
2040 | 2076 | addToPool(g2, pwl2); |
2041 | 2077 | } |
2042 | | - if (qaflags.doSinglePhotonQa) { |
| 2078 | + if (mDoSinglePhotonQa) { |
2043 | 2079 | for (const auto& g : photons1Coll) { |
2044 | 2080 | if (cut1.template IsSelected<decltype(g), TSubInfos1>(g)) { |
2045 | 2081 | if (idsAfterPairCuts.contains(g.globalIndex())) { |
@@ -2070,6 +2106,9 @@ struct Photonhbt { |
2070 | 2106 | if (!passAsymmetryCut(g1.pt(), g2.pt())) { |
2071 | 2107 | continue; |
2072 | 2108 | } |
| 2109 | + if (!passFastQinvGate(g1, g2)) { |
| 2110 | + continue; |
| 2111 | + } |
2073 | 2112 | auto obs = buildPairQAObservables(g1, g2); |
2074 | 2113 | if (!obs.valid) { |
2075 | 2114 | continue; |
@@ -2170,7 +2209,7 @@ struct Photonhbt { |
2170 | 2209 | auto keyBin = std::make_tuple(zbin, centbin, epbin, occbin); |
2171 | 2210 | auto keyDFCollision = std::make_pair(ndf, collision.globalIndex()); |
2172 | 2211 | auto photonsColl = photons.sliceBy(perCollision, collision.globalIndex()); |
2173 | | - if (qaflags.doSinglePhotonQa) { |
| 2212 | + if (mDoSinglePhotonQa) { |
2174 | 2213 | for (const auto& g : photonsColl) { |
2175 | 2214 | if (cut.template IsSelected<decltype(g), TLegs>(g)) { |
2176 | 2215 | fillSinglePhotonQAStep<0>(g); |
@@ -2265,7 +2304,9 @@ struct Photonhbt { |
2265 | 2304 | } else { |
2266 | 2305 | const bool doMCQA = passQinvMCQAGate(obs.qinv); |
2267 | 2306 | fillMCPairQA<false>(truthType, obs, doQA, doMCQA); |
2268 | | - fillLegPairMC(truthType, legObs, obs.kt); |
| 2307 | + if (mDoLegPairQA) { |
| 2308 | + fillLegPairMC(truthType, legObs, obs.kt); |
| 2309 | + } |
2269 | 2310 | if (doFR) { |
2270 | 2311 | fillMCPairQAFullRange<false>(truthType, obs); |
2271 | 2312 | } |
@@ -2318,7 +2359,7 @@ struct Photonhbt { |
2318 | 2359 | addToPool(g1, pwl1); |
2319 | 2360 | addToPool(g2, pwl2); |
2320 | 2361 | } |
2321 | | - if (qaflags.doSinglePhotonQa) { |
| 2362 | + if (mDoSinglePhotonQa) { |
2322 | 2363 | for (const auto& g : photonsColl) { |
2323 | 2364 | if (cut.template IsSelected<decltype(g), TLegs>(g)) { |
2324 | 2365 | if (idsAfterPairCuts.contains(g.globalIndex())) { |
@@ -2349,6 +2390,9 @@ struct Photonhbt { |
2349 | 2390 | if (!passAsymmetryCut(g1.pt(), g2.pt())) { |
2350 | 2391 | continue; |
2351 | 2392 | } |
| 2393 | + if (!passFastQinvGate(g1, g2)) { |
| 2394 | + continue; |
| 2395 | + } |
2352 | 2396 | auto obs = buildPairQAObservables(g1, g2); |
2353 | 2397 | if (!obs.valid) { |
2354 | 2398 | continue; |
|
0 commit comments