25 using namespace asg::msgUserCode;
28 if (argc < 3 || argc > 4) {
29 std::cerr <<
"usage: " <<
argv[0] <<
": <DAOD> <jet collection> [max events]"
31 <<
"This test checks jet constituents and their thinning.\n"
32 <<
"It verifies that:\n"
33 <<
" 1. All jet constituent links are valid\n"
34 <<
" 2. All constituents can be cast to FlowElement\n"
35 <<
" 3. Counts charged vs neutral constituents\n"
36 <<
" 4. Checks originalObjectLink availability\n"
37 <<
" 5. Validates otherObjects pointers\n"
40 <<
" <DAOD> : Input DAOD file path\n"
41 <<
" <jet collection>: Name of jet collection to check\n"
42 <<
" [max events] : Optional maximum number of events to process\n"
45 <<
" -1: usage error\n"
46 <<
" 1: broken constituent links found\n"
47 <<
" 2: constituent not a FlowElement\n"
48 <<
" 3: invalid otherObjects in charged FlowElements\n"
49 <<
" 4: invalid otherObjects in neutral FlowElements\n"
50 <<
" 0: all constituents valid" << std::endl;
54 std::string jets_name =
argv[2];
61 const std::string
APP_NAME =
"TestJetConstituents";
70 std::unique_ptr<TFile>
ifile(TFile::Open(
file.c_str(),
"READ"));
72 std::cerr <<
"Couldn't open file: " <<
file << std::endl;
79 unsigned long long nJetsTotal = 0;
80 unsigned long long nConstituentsTotal = 0;
81 unsigned long long nChargedTotal = 0;
82 unsigned long long nNeutralTotal = 0;
83 unsigned long long nInvalidLinks = 0;
84 unsigned long long nNotFlowElement = 0;
85 unsigned long long nWithOriginalLink = 0;
86 unsigned long long nOtherObjectsCharged = 0;
87 unsigned long long nOtherObjectsNeutral = 0;
88 unsigned long long nInvalidOtherObjectsCharged = 0;
89 unsigned long long nInvalidOtherObjectsNeutral = 0;
90 unsigned long long nMissingSignalType = 0;
92 unsigned long long entries =
event.getEntries();
96 std::cout <<
"Processing " <<
entries <<
" events..." << std::endl;
101 std::cerr <<
"Couldn't load entry " <<
entry <<
" from file "
102 <<
file << std::endl;
111 size_t nConstituents =
jet->numConstituents();
112 nConstituentsTotal += nConstituents;
114 for (
size_t i = 0;
i < nConstituents; ++
i) {
115 const auto& link =
jet->constituentLinks().at(
i);
118 if (!link.isValid()) {
131 constituent = *origLink;
152 std::vector<const xAOD::IParticle*> others = flowElement->
otherObjects();
155 nOtherObjectsCharged++;
157 nInvalidOtherObjectsCharged++;
160 nOtherObjectsNeutral++;
162 nInvalidOtherObjectsNeutral++;
171 std::cout <<
"\n========================================" << std::endl;
172 std::cout <<
"SUMMARY" << std::endl;
173 std::cout <<
"========================================" << std::endl;
174 std::cout <<
"Events processed: " <<
entries << std::endl;
175 std::cout <<
"Jets found: " << nJetsTotal << std::endl;
176 std::cout <<
"Total constituents: " << nConstituentsTotal << std::endl;
177 std::cout <<
" Charged: " << nChargedTotal
178 <<
" (" << std::fixed << std::setprecision(1)
179 << (nConstituentsTotal > 0 ? 100.0 * nChargedTotal / nConstituentsTotal : 0.0)
180 <<
"%)" << std::endl;
181 std::cout <<
" Neutral: " << nNeutralTotal
182 <<
" (" << std::fixed << std::setprecision(1)
183 << (nConstituentsTotal > 0 ? 100.0 * nNeutralTotal / nConstituentsTotal : 0.0)
184 <<
"%)" << std::endl;
185 std::cout <<
"Invalid constituent links: " << nInvalidLinks << std::endl;
186 std::cout <<
"Non-FlowElement constituents: " << nNotFlowElement << std::endl;
187 std::cout <<
"Missing signalType: " << nMissingSignalType << std::endl;
188 std::cout <<
"Constituents with originalObjectLink: " << nWithOriginalLink << std::endl;
189 std::cout <<
"\nOther Objects:" << std::endl;
190 std::cout <<
" Charged otherObjects: " << nOtherObjectsCharged;
191 if (nInvalidOtherObjectsCharged > 0) {
192 std::cout <<
" (INVALID: " << nInvalidOtherObjectsCharged <<
")";
194 std::cout << std::endl;
195 std::cout <<
" Neutral otherObjects: " << nOtherObjectsNeutral;
196 if (nInvalidOtherObjectsNeutral > 0) {
197 std::cout <<
" (INVALID: " << nInvalidOtherObjectsNeutral <<
")";
199 std::cout << std::endl;
200 std::cout <<
" Total otherObjects: " << (nOtherObjectsCharged + nOtherObjectsNeutral) << std::endl;
202 if (nConstituentsTotal > 0) {
203 std::cout <<
"\nAverage constituents/jet: " << std::fixed << std::setprecision(2)
204 << (
double)nConstituentsTotal / nJetsTotal << std::endl;
206 std::cout <<
"========================================\n" << std::endl;
209 if (nInvalidLinks > 0) {
210 std::cerr <<
"ERROR: Found " << nInvalidLinks <<
" invalid constituent links!" << std::endl;
213 if (nNotFlowElement > 0) {
214 std::cerr <<
"ERROR: Found " << nNotFlowElement <<
" constituents that are not FlowElements!" << std::endl;
217 if (nInvalidOtherObjectsCharged > 0) {
218 std::cerr <<
"ERROR: Found " << nInvalidOtherObjectsCharged <<
" invalid otherObjects in charged FlowElements!" << std::endl;
221 if (nInvalidOtherObjectsNeutral > 0) {
222 std::cerr <<
"ERROR: Found " << nInvalidOtherObjectsNeutral <<
" invalid otherObjects in neutral FlowElements!" << std::endl;
226 std::cout <<
"SUCCESS: All constituent links are valid!" << std::endl;