Skip to content

Commit d1f2e9a

Browse files
committed
Add dedicated CI macro for 5.36 TeV LF resonances
Provide GeneratorLF_Resonances_pp5360_Rare.C with the existing Rare injection PDG, decay, and gap sanity checks. Remove the INI test redirection so CI discovers the dedicated macro by filename. Validation: the actual generator CI runner passed with 100 events, including DPL eventgen, o2-sim --noGeant, generic kinematics, and the dedicated External macro.
1 parent a68c3fd commit d1f2e9a

2 files changed

Lines changed: 112 additions & 1 deletion

File tree

‎MC/config/PWGLF/ini/GeneratorLF_Resonances_pp5360_Rare.ini‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
#---> GeneratorLF_Resonances_pp_Rare
21
[GeneratorExternal]
32
fileName=${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator_pythia8_LF_rapidity_width.C
43
funcName=generateLFRapidity("${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/resonancelistgun_width_inj.json", true, 5, false, true, "${O2DPG_MC_CONFIG_ROOT}/MC/config/PWGLF/pythia8/generator/pythia8_inel_pp536tev.cfg", "")
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
// Dedicated kinematics test for Rare resonance injection in pp at 5.36 TeV.
2+
3+
int External()
4+
{
5+
const std::string path{"o2sim_Kine.root"};
6+
const int numberOfGapEvents{4}; // generateLFRapidity(..., gap=5)
7+
const std::vector<int> injectedPDGs = {
8+
9010221, // f0(980)
9+
3324, -3324, // Xi(1530)0 and anti-Xi(1530)0
10+
123324, -123324, // Xi(1820)0 and anti-Xi(1820)0
11+
123314, -123314, // Xi(1820)- and Xi(1820)+
12+
123334, -123334 // Omega(2012)- and Omega(2012)+
13+
};
14+
const std::vector<std::vector<int>> decayDaughters = {
15+
{211, -211},
16+
{3312, 211}, {-3312, -211},
17+
{3122, 310}, {-3122, 310},
18+
{3122, -321}, {-3122, 321},
19+
{3312, 310}, {-3312, 310}
20+
};
21+
22+
TFile file(path.c_str(), "READ");
23+
if (file.IsZombie()) {
24+
std::cerr << "Cannot open ROOT file " << path << "\n";
25+
return 1;
26+
}
27+
auto tree = (TTree*)file.Get("o2sim");
28+
if (!tree) {
29+
std::cerr << "Cannot find tree o2sim in file " << path << "\n";
30+
return 1;
31+
}
32+
std::vector<o2::MCTrack>* tracks{};
33+
tree->SetBranchAddress("MCTrack", &tracks);
34+
35+
std::vector<int> nSignal(injectedPDGs.size(), 0);
36+
std::vector<int> nNotDecayed(injectedPDGs.size(), 0);
37+
std::vector<std::vector<int>> nDecays;
38+
for (const auto& daughters : decayDaughters) {
39+
nDecays.emplace_back(daughters.size(), 0);
40+
}
41+
42+
int numberOfEventsProcessed{0};
43+
int numberOfEventsProcessedWithoutInjection{0};
44+
for (Long64_t i = 0; i < tree->GetEntries(); ++i) {
45+
tree->GetEntry(i);
46+
++numberOfEventsProcessed;
47+
bool hasInjection{false};
48+
for (const auto& track : *tracks) {
49+
const auto pdg = track.GetPdgCode();
50+
const auto it = std::find(injectedPDGs.begin(), injectedPDGs.end(), pdg);
51+
if (it == injectedPDGs.end()) {
52+
continue;
53+
}
54+
const auto index = static_cast<size_t>(std::distance(injectedPDGs.begin(), it));
55+
++nSignal[index];
56+
if (track.getFirstDaughterTrackId() < 0) {
57+
++nNotDecayed[index];
58+
continue;
59+
}
60+
for (int j = track.getFirstDaughterTrackId(); j <= track.getLastDaughterTrackId(); ++j) {
61+
const auto pdgDau = tracks->at(j).GetPdgCode();
62+
bool foundDau{false};
63+
for (size_t k = 0; k < decayDaughters[index].size(); ++k) {
64+
if (pdgDau == decayDaughters[index][k]) {
65+
++nDecays[index][k];
66+
foundDau = true;
67+
hasInjection = true;
68+
break;
69+
}
70+
}
71+
if (!foundDau) {
72+
std::cerr << "Decay daughter not found: " << pdg << " -> " << pdgDau
73+
<< " (mother=" << track.getMotherTrackId()
74+
<< ", secondMother=" << track.getSecondMotherTrackId() << ")\n";
75+
}
76+
}
77+
}
78+
if (!hasInjection) {
79+
++numberOfEventsProcessedWithoutInjection;
80+
}
81+
}
82+
83+
std::cout << "--------------------------------\n";
84+
std::cout << "# Events: " << tree->GetEntries() << "\n";
85+
for (size_t i = 0; i < injectedPDGs.size(); ++i) {
86+
std::cout << "# Mother\n";
87+
std::cout << injectedPDGs[i] << " generated: " << nSignal[i]
88+
<< ", " << nNotDecayed[i] << " did not decay\n";
89+
for (size_t j = 0; j < decayDaughters[i].size(); ++j) {
90+
std::cout << "# Daughter " << decayDaughters[i][j] << ": " << nDecays[i][j] << "\n";
91+
}
92+
}
93+
std::cout << "--------------------------------\n";
94+
std::cout << "Number of events processed: " << numberOfEventsProcessed << "\n";
95+
std::cout << "Number of input for the gap events: " << numberOfGapEvents << "\n";
96+
std::cout << "Number of events processed without injection: "
97+
<< numberOfEventsProcessedWithoutInjection << "\n";
98+
const double ratioOfNormalEvents = numberOfEventsProcessed
99+
? static_cast<double>(numberOfEventsProcessedWithoutInjection) /
100+
numberOfEventsProcessed
101+
: 0.0;
102+
std::cout << "Fraction without injection: " << ratioOfNormalEvents << "\n";
103+
const double expectedRatio = static_cast<double>(numberOfGapEvents) / (numberOfGapEvents + 1);
104+
std::cout << "Expected fraction for 1+" << numberOfGapEvents << " pattern: " << expectedRatio << "\n";
105+
106+
// Same basic gap sanity check as the referenced O2DPG test.
107+
if (ratioOfNormalEvents > 0.90 || ratioOfNormalEvents < 0.70) {
108+
std::cerr << "The number of injected events is too low or too high\n";
109+
return 1;
110+
}
111+
return 0;
112+
}

0 commit comments

Comments
 (0)