Skip to content

Commit 014c9b0

Browse files
Implement mixed-event configuration and handling
Added mixing configuration for mixed-event analysis and integrated it into the data processing logic.
1 parent 37a9123 commit 014c9b0

1 file changed

Lines changed: 49 additions & 0 deletions

File tree

PWGHF/D2H/Tasks/taskCd.cxx

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,12 @@ struct HfTaskCd {
257257
using CollisionsWithEvSelFT0M = soa::Join<aod::Collisions, aod::EvSels, aod::PVMults, aod::CentFT0Ms>;
258258
using CollisionsMcWithEvSelFT0M = soa::Join<aod::Collisions, aod::McCollisionLabels, aod::EvSels, aod::PVMults, aod::CentFT0Ms>;
259259

260+
struct : ConfigurableGroup {
261+
std::string prefix = "mixing";
262+
Configurable<bool> enabled{"enabled", false, "Analyze mixed-event input in a separate run"};
263+
Configurable<int> type{"type", 0, "QA label matching builder mixing.type: 0 d, 1 K, 2 pion"};
264+
} mixing;
265+
260266
using CdCandidates = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelCd, aod::HfCand3ProngWPidPiKaDe>>;
261267
using CdCandidatesMc = soa::Filtered<soa::Join<aod::HfCand3Prong, aod::HfSelCd, aod::HfCand3ProngWPidPiKaDe, aod::HfCand3ProngMcRec>>;
262268
using McParticles3ProngMatched = soa::Join<aod::McParticles, aod::HfCand3ProngMcGen>;
@@ -327,6 +333,30 @@ struct HfTaskCd {
327333
}
328334
const bool isData = doprocessDataStd || doprocessDataStdWithFT0C || doprocessDataStdWithFT0M;
329335

336+
if (mixing.enabled) {
337+
constexpr int LastMixingType{2};
338+
if (!isData || mixing.type < 0 || mixing.type > LastMixingType) {
339+
LOGP(fatal, "Mixed-event taskCd requires a data process and a valid mixing.type.");
340+
}
341+
registry.add("Mixed/hMassVsPtVsType", "Mixed candidates after selector;M(dK#pi);p_{T};mixing type", HistType::kTH3F,
342+
{{400, 2.4, 4.4}, {binsPt, "p_{T}"}, {3, -0.5, 2.5}});
343+
}
344+
if (isData && (fillCandLiteTree || fillCandFullTree)) {
345+
registry.add("Data/hTreeCutFlow", "Cumulative write preselection per mass hypothesis;Stage;Hypothesis", HistType::kTH2D, {{4, -0.5, 3.5}, {2, -0.5, 1.5}});
346+
registry.add("Data/hDeuteronTofStatus", "TOF status before write preselection;Status;Hypothesis", HistType::kTH2D, {{5, -0.5, 4.5}, {2, -0.5, 1.5}});
347+
const std::array<std::string, 4> cutLabels{"Before tree cuts", "After TOF (or disabled)", "After minimum d DCA", "After DCA ordering (or disabled)"};
348+
const std::array<std::string, 5> tofLabels{"No TOF match", "Nonfinite nSigma", "Missing nSigma sentinel", "Finite nSigma within cut", "Finite nSigma outside cut"};
349+
for (size_t i = 0; i < cutLabels.size(); ++i) {
350+
registry.get<TH2>(HIST("Data/hTreeCutFlow"))->GetXaxis()->SetBinLabel(i + 1, cutLabels[i].c_str());
351+
}
352+
for (size_t i = 0; i < tofLabels.size(); ++i) {
353+
registry.get<TH2>(HIST("Data/hDeuteronTofStatus"))->GetXaxis()->SetBinLabel(i + 1, tofLabels[i].c_str());
354+
}
355+
for (const auto& histogram : {registry.get<TH2>(HIST("Data/hTreeCutFlow")), registry.get<TH2>(HIST("Data/hDeuteronTofStatus"))}) {
356+
histogram->GetYaxis()->SetBinLabel(1, "DeKPi");
357+
histogram->GetYaxis()->SetBinLabel(2, "PiKDe");
358+
}
359+
}
330360
auto addHistogramsRec = [&](const std::string& histoName, const std::string& xAxisTitle, const std::string& yAxisTitle, const HistogramConfigSpec& configSpec) {
331361
if (!isData) {
332362
registry.add(("MC/reconstructed/signal/" + histoName + "RecSig").c_str(), ("3-prong candidates (matched);" + xAxisTitle + ";" + yAxisTitle).c_str(), configSpec);
@@ -768,6 +798,14 @@ struct HfTaskCd {
768798
const auto chi2PCA = candidate.chi2PCA();
769799
const auto cpa = candidate.cpa();
770800
const auto cpaXY = candidate.cpaXY();
801+
if (mixing.enabled) {
802+
if (candidate.isSelCdToDeKPi() >= selectionFlagCd) {
803+
registry.fill(HIST("Mixed/hMassVsPtVsType"), HfHelper::invMassCdToDeKPi(candidate), candidate.pt(), mixing.type.value);
804+
}
805+
if (candidate.isSelCdToPiKDe() >= selectionFlagCd) {
806+
registry.fill(HIST("Mixed/hMassVsPtVsType"), HfHelper::invMassCdToPiKDe(candidate), candidate.pt(), mixing.type.value);
807+
}
808+
}
771809
if (candidate.isSelCdToDeKPi() >= selectionFlagCd) {
772810
registry.fill(HIST("Data/hMass"), HfHelper::invMassCdToDeKPi(candidate));
773811
registry.fill(HIST("Data/hMassVsPtVsNPvContributors"), HfHelper::invMassCdToDeKPi(candidate), pt, numPvContributors);
@@ -874,16 +912,27 @@ struct HfTaskCd {
874912
registry.fill(HIST("Data/hNsigmaTPCKaVsP"), prong1.tpcInnerParam() * prong1.sign(), nSigmaTpcKa);
875913
registry.fill(HIST("Data/hNsigmaTOFKaVsP"), prong1.tpcInnerParam() * prong1.sign(), nSigmaTofKa);
876914

915+
// Diagnostic categories only: preserve the existing selection predicates below.
916+
enum TofStatus { NoMatch, Nonfinite, Missing, WithinCut, OutsideCut };
917+
constexpr float MissingTofNSigma{-999.f};
918+
const int hypothesis = isDeKPi ? 0 : 1;
919+
const int tofStatus = !deuteronProng.hasTOF() ? NoMatch : !std::isfinite(nSigmaTofDe) ? Nonfinite : nSigmaTofDe <= MissingTofNSigma ? Missing : std::abs(nSigmaTofDe) <= cfgMaxDeuteronTofPidPreselection ? WithinCut : OutsideCut;
920+
registry.fill(HIST("Data/hDeuteronTofStatus"), tofStatus, hypothesis);
921+
registry.fill(HIST("Data/hTreeCutFlow"), 0, hypothesis);
877922
if (cfgUseTofPidForDeuteron && std::abs(nSigmaTofDe) > cfgMaxDeuteronTofPidPreselection) {
878923
return;
879924
}
925+
registry.fill(HIST("Data/hTreeCutFlow"), 1, hypothesis);
880926
if (std::abs(dcaDeuteron) < cfgMinDeuteronDcaPreselection) {
881927
return;
882928
}
929+
registry.fill(HIST("Data/hTreeCutFlow"), 2, hypothesis);
883930
if (cfgCutOnDeuteronDcaOrdering && (std::abs(dcaDeuteron) > std::abs(dcaKaon) || std::abs(dcaDeuteron) > std::abs(dcaPion))) {
884931
return;
885932
}
886933

934+
registry.fill(HIST("Data/hTreeCutFlow"), 3, hypothesis);
935+
887936
if (fillCandLiteTree) {
888937
rowCandCdLite(
889938
invMassCd, invMassLc, pt, eta, phi, ptProng0, ptProng1, ptProng2,

0 commit comments

Comments
 (0)