ATLAS Offline Software
NavigationTesterAlg.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include <GaudiKernel/StatusCode.h>
6 #include <set>
7 #include <algorithm>
8 #include <iterator>
10 #include "NavigationTesterAlg.h"
11 #include "SpecialCases.h"
12 
13 
14 // anonymous namespace for convenience functions
15 namespace {
16  std::set<std::set<const xAOD::IParticle *>> vectorToSet(
17  const std::vector<std::vector<const xAOD::IParticle *>>& vec)
18  {
19  std::set<std::set<const xAOD::IParticle *>> ret;
20  for (const std::vector<const xAOD::IParticle *> &combination : vec)
21  ret.emplace(combination.begin(), combination.end());
22  return ret;
23  }
24 
25 }
26 
27 namespace xAOD {
28  std::ostream &operator<<(std::ostream &os, const xAOD::IParticle *p)
29  {
30  return os << "["
31  << "type = " << p->type() << ", "
32  << "pt = " << p->pt() << ", "
33  << "eta = " << p->eta() << ", "
34  << "phi = " << p->phi() << ", "
35  << "ptr = " << reinterpret_cast<const void*>(p)
36  << "]";
37 
38  }
39 }
40 
41 namespace std {
42  // Define printing operators for the set and IParticle pointers
43  template <typename T>
44  std::ostream &operator<<(std::ostream &os, const std::set<T> &s)
45  {
46  os << "{";
47  for (auto itr = s.begin(); itr != s.end(); ++itr)
48  {
49  if (itr != s.begin())
50  os << ", ";
51  os << *itr;
52  }
53  return os << "}";
54  }
55 }
56 
57 namespace Trig {
58 
59  NavigationTesterAlg::NavigationTesterAlg(const std::string &name, ISvcLocator *pSvcLocator) :
60  AthReentrantAlgorithm(name, pSvcLocator)
61  {}
62 
64  {
65  ATH_CHECK(m_tdt.retrieve());
66  ATH_CHECK(m_tdtRun2.retrieve());
67  ATH_CHECK(m_tdtRun3.retrieve());
68  ATH_CHECK(m_toolRun2.retrieve());
69  ATH_CHECK(m_toolRun3.retrieve());
70 
71  if (m_chains.size() == 0)
72  ATH_MSG_WARNING("No chains provided, algorithm will be no-op");
73  return StatusCode::SUCCESS;
74  }
75 
76  StatusCode NavigationTesterAlg::execute(const EventContext &) const
77  {
78  for (const std::string &chain : m_chains)
79  {
80  ATH_MSG_DEBUG("Begin testing chain " << chain << (m_tdt->isPassed(chain) ? " and will dive into details as the chain passed " : " but will not do anything as the chain did not pass"));
81  if (!m_tdt->isPassed(chain)) continue;
82 
83  // explicitely excluded chains
84  bool isExcluded = false;
85  for (const auto& excludedChain : SpecialCases::excludedChains) {
86  if (chain == excludedChain) {
87  isExcluded = true;
88  break; // Break out of the exclusion check loop
89  }
90  }
91 
92  if (isExcluded) {
93  continue; // Skip the current iteration of the main loop
94  }
95 
96  // We assume that the navigation is ultimately a set of element links
97  // We're comparing two types of navigation but they should both point to the same
98  // objects.
99  // We don't care about the order of the combinations, or the order within the
100  // combinations, we just care that they are the same. Therefore, we can convert the
101  // vectors to sets and just look at the differences between them
102  CombinationsVector vecCombinationsRun2;
103  ATH_MSG_DEBUG("###### checking features of CHAIN " << chain);
104  ATH_CHECK(m_toolRun2->retrieveParticles(vecCombinationsRun2, chain));
105  auto combsRun2 = vectorToSet(vecCombinationsRun2);
106  ATH_MSG_DEBUG("Run 2 size " << combsRun2.size());
107  // if Run 2 size is 0 we discard any further testing
108  if (combsRun2.size() == 0)
109  {
110  ATH_MSG_DEBUG("Chain " << chain << " testing discarded due to detected Run 2 size == 0");
111  continue;
112  }
113  for (auto& c : combsRun2 ) {
114  ATH_MSG_DEBUG(c);
115  }
116  CombinationsVector vecCombinationsRun3;
117  ATH_CHECK(m_toolRun3->retrieveParticles(vecCombinationsRun3, chain));
118  auto combsRun3 = vectorToSet(vecCombinationsRun3);
119  ATH_MSG_DEBUG("Run 3 size " << combsRun3.size());
120 
121  if (combinationsEmpty(vecCombinationsRun2) and combinationsEmpty(vecCombinationsRun3)) {
122  ATH_MSG_DEBUG("Both, Run2 and Run3 combinations are effectively empty");
123  continue;
124  }
125 
126 
127  for (auto& c : combsRun3 ) {
128  ATH_MSG_DEBUG(c);
129  }
130  if ( std::regex_match(chain, SpecialCases::gammaXeChain) ) {
132  } else {
133  if ( m_verifyCombinationsSize ) {
134  ATH_CHECK(verifyCombinationsSize(vecCombinationsRun2, vecCombinationsRun3, chain));
135  }
136  if ( m_verifyCombinations ) {
137  ATH_CHECK(verifyCombinationsContent(combsRun2, combsRun3, chain));
138  }
139  }
140 
141  ATH_MSG_DEBUG("Verified chain " << chain);
142  }
143  return StatusCode::SUCCESS;
144  }
145 
147  const auto &run3 = m_tdtRun3->features<xAOD::IParticleContainer>(chain);
148  std::set<const xAOD::IParticle*> particlesRun3;
149  for ( auto l: run3) {
150  if ( l.link.isValid() )
151  particlesRun3.insert(*(l.link));
152  }
153 
154  CombinationsVector vecCombinationsRun2;
155  ATH_CHECK(m_toolRun2->retrieveParticles(vecCombinationsRun2, chain));
156  std::set<const xAOD::IParticle*> particlesRun2;
157  for ( auto& comb: vecCombinationsRun2) {
158  for ( auto el: comb) {
159  particlesRun2.insert(el);
160  }
161  }
162 
163  for ( auto f2: particlesRun2 ) {
164  bool found=false;
165  for ( auto f3: particlesRun3 ) {
166  ATH_MSG_DEBUG("Serial set of features " << f3 );
167  if ( f2 == f3)
168  found = true;
169  }
170  if ( not found ) {
171  ATH_MSG_ERROR("Missing feature in Run 3 that is present in Run 2 " << f2 << " chain " << chain << " enable DEBUG to see more details" );
172  if ( m_failOnDifference ) {
173  return StatusCode::FAILURE;
174  }
175  }
176  }
177  return StatusCode::SUCCESS;
178  }
179 
180 
182  if (run2.size() > run3.size()) { // in Run3 we do not use decision per RoI but per object. For single RoI there is more than one object we will have more combinations in Run3
183  ATH_MSG_WARNING("Issue in combination sizes for chain " << chain
184  << " using Run 2 navigation " << run2.size()
185  << " Run 3 navigation " << run3.size());
186  ATH_MSG_ERROR("Mismatched sizes of combinations for chain " << chain << " (enable WARNING messages for more details), this may be a false positive if chain is incorrectly decoded");
187  if ( m_failOnDifference ) {
188  return StatusCode::FAILURE;
189  }
190  }
191  return StatusCode::SUCCESS;
192  }
193 
195  // compare combinations
196 
197  using xAODParticle = const xAOD::IParticle;
198 
199  auto isSubsetPresent = [](const std::set<xAODParticle*>& subset, const CombinationsSet& run2) {
200  for (const auto& setInRun2 : run2) {
201  // Manual check for all particles in subset
202  bool allFound = true;
203  for (auto particle : subset) {
204  if (setInRun2.find(particle) == setInRun2.end()) {
205  allFound = false;
206  break; // If any particle is not found, no need to check further
207  }
208  }
209  if (allFound) return true; // Found all particles in this subset of Run2
210  }
211  return false; // Did not find the subset
212  };
213 
214 
215  auto isAnySubsetPresent = [&isSubsetPresent](const CombinationsSet& run3, const CombinationsSet& run2) {
216  for (const auto& subset : run3) {
217  if (isSubsetPresent(subset, run2)) {
218  return true; // At least one subset from Run3 is found in Run2
219  }
220  }
221  return false; // No subset from Run3 was found in Run2
222  };
223 
224  bool result { false };
225  // hack for "HLT_e26_lhmedium_nod0_mu8noL1" case
226  // hack for "HLT_e24_lhmedium_L1EM20VHI_mu8noL1" type case
227  // hack for "HLT_mu11_2mu4noL1_nscan03_L1MU11_2MU6" type case
228  if ( std::regex_match(chain, SpecialCases::specialEchain) or
229  std::regex_match(chain, SpecialCases::specialElMuChain) or
230  std::regex_match(chain, SpecialCases::mu2MunoL1Special) ) {
231  result = isAnySubsetPresent(run3, run2);
232  } else {
233  // now subset checked on a level of objects, instead of group of objects
234  result = isAnySubsetPresent(run2, run3);
235  }
236 
237  if (run2 != run3)
238  {
239  ATH_MSG_WARNING("Difference in combinations between Run2 and Run3 format for chain: " << chain << " parsed multiplicities " << ChainNameParser::multiplicities(chain));
240  ATH_MSG_WARNING("Run2 combs: " << run2);
241  ATH_MSG_WARNING("Run3 combs: " << run3);
242  }
243 
244  if (not result) // previous not isSubset, loosened condition
245  {
246  ATH_MSG_WARNING("NOT PASSED: failed, Run2 objects are not within a subset of Run3 objects for chain: " << chain << " parsed multiplicities " << ChainNameParser::multiplicities(chain));
247  ATH_MSG_WARNING("Run2 combs: " << run2);
248  ATH_MSG_WARNING("Run3 combs: " << run3);
249  if ( m_failOnDifference ) {
250  return StatusCode::FAILURE;
251  }
252  }
253 
254  return StatusCode::SUCCESS;
255  }
256 
258  size_t counter = 0;
259  for ( const std::vector<const xAOD::IParticle*>& outerc: combs )
260  counter += outerc.size();
261  return counter == 0;
262  }
263 
264 } //> end namespace Trig
265 
266 
NavigationTesterAlg.h
SpecialCases::mu2MunoL1Special
const std::regex mu2MunoL1Special
Definition: SpecialCases.h:36
Trk::ParticleSwitcher::particle
constexpr ParticleHypothesis particle[PARTICLEHYPOTHESES]
the array of masses
Definition: ParticleHypothesis.h:76
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Trig::NavigationTesterAlg::m_tdtRun3
PublicToolHandle< Trig::TrigDecisionTool > m_tdtRun3
Definition: NavigationTesterAlg.h:25
SpecialCases::specialEchain
const std::regex specialEchain
Definition: SpecialCases.h:34
ChainNameParser.h
get_generator_info.result
result
Definition: get_generator_info.py:21
Trig::NavigationTesterAlg::m_verifyCombinations
Gaudi::Property< bool > m_verifyCombinations
Definition: NavigationTesterAlg.h:40
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
Trig::NavigationTesterAlg::CombinationsVector
std::vector< std::vector< const xAOD::IParticle * > > CombinationsVector
Definition: NavigationTesterAlg.h:44
Trig::NavigationTesterAlg::initialize
StatusCode initialize() override
Definition: NavigationTesterAlg.cxx:63
Trig
The common trigger namespace for trigger analysis tools.
Definition: LArCellMonAlg.h:33
Trig::NavigationTesterAlg::NavigationTesterAlg
NavigationTesterAlg(const std::string &name, ISvcLocator *pSvcLocator)
Definition: NavigationTesterAlg.cxx:59
Trig::NavigationTesterAlg::verifyCombinationsContent
StatusCode verifyCombinationsContent(const CombinationsSet &run2, const CombinationsSet &run3, const std::string &chain) const
Definition: NavigationTesterAlg.cxx:194
SpecialCases.h
Trig::NavigationTesterAlg::m_toolRun3
ToolHandle< Trig::IIParticleRetrievalTool > m_toolRun3
Definition: NavigationTesterAlg.h:30
xAOD
ICaloAffectedTool is abstract interface for tools checking if 4 mom is in calo affected region.
Definition: ICaloAffectedTool.h:24
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
Trig::NavigationTesterAlg::m_verifyCombinationsSize
Gaudi::Property< bool > m_verifyCombinationsSize
Definition: NavigationTesterAlg.h:37
Trig::NavigationTesterAlg::CombinationsSet
std::set< std::set< const xAOD::IParticle * > > CombinationsSet
Definition: NavigationTesterAlg.h:45
vec
std::vector< size_t > vec
Definition: CombinationsGeneratorTest.cxx:12
Trig::NavigationTesterAlg::combinationsEmpty
bool combinationsEmpty(const CombinationsVector &combs) const
Definition: NavigationTesterAlg.cxx:257
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
SpecialCases::gammaXeChain
const std::regex gammaXeChain
Definition: SpecialCases.h:29
AthReentrantAlgorithm
An algorithm that can be simultaneously executed in multiple threads.
Definition: AthReentrantAlgorithm.h:83
read_hist_ntuple.f2
f2
Definition: read_hist_ntuple.py:20
xAOD::EgammaParameters::f3
@ f3
fraction of energy reconstructed in 3rd sampling
Definition: EgammaEnums.h:54
RunTileCalibRec.run3
run3
Definition: RunTileCalibRec.py:208
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
Trig::NavigationTesterAlg::verifyFlatContent
StatusCode verifyFlatContent(const std::string &chain) const
Definition: NavigationTesterAlg.cxx:146
EL::StatusCode
::StatusCode StatusCode
StatusCode definition for legacy code.
Definition: PhysicsAnalysis/D3PDTools/EventLoop/EventLoop/StatusCode.h:22
ATH_MSG_DEBUG
#define ATH_MSG_DEBUG(x)
Definition: AthMsgStreamMacros.h:29
Trig::NavigationTesterAlg::verifyCombinationsSize
StatusCode verifyCombinationsSize(const CombinationsVector &run2, const CombinationsVector &run3, const std::string &chain) const
Definition: NavigationTesterAlg.cxx:181
Trig::NavigationTesterAlg::execute
StatusCode execute(const EventContext &context) const override
Definition: NavigationTesterAlg.cxx:76
plotIsoValidation.el
el
Definition: plotIsoValidation.py:197
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
DataVector::insert
iterator insert(iterator position, value_type pElem)
Add a new element to the collection.
SpecialCases::excludedChains
const std::vector< std::string > excludedChains
Definition: SpecialCases.h:8
DataVector
Derived DataVector<T>.
Definition: DataVector.h:794
ReadFromCoolCompare.os
os
Definition: ReadFromCoolCompare.py:231
Trig::NavigationTesterAlg::m_tdtRun2
PublicToolHandle< Trig::TrigDecisionTool > m_tdtRun2
Definition: NavigationTesterAlg.h:26
ReadCellNoiseFromCoolCompare.run2
run2
Definition: ReadCellNoiseFromCoolCompare.py:53
Trig::NavigationTesterAlg::m_chains
Gaudi::Property< std::vector< std::string > > m_chains
Definition: NavigationTesterAlg.h:32
ChainNameParser::multiplicities
std::vector< int > multiplicities(const std::string &chain)
Definition: ChainNameParser.cxx:202
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:228
operator<<
std::ostream & operator<<(std::ostream &lhs, const TestGaudiProperty &rhs)
Definition: TestGaudiProperty.cxx:69
Trig::NavigationTesterAlg::m_failOnDifference
Gaudi::Property< bool > m_failOnDifference
Definition: NavigationTesterAlg.h:34
CondAlgsOpts.found
int found
Definition: CondAlgsOpts.py:101
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
Trig::NavigationTesterAlg::m_tdt
PublicToolHandle< Trig::TrigDecisionTool > m_tdt
Definition: NavigationTesterAlg.h:24
SpecialCases::specialElMuChain
const std::regex specialElMuChain
Definition: SpecialCases.h:35
test_pyathena.counter
counter
Definition: test_pyathena.py:15
Trig::NavigationTesterAlg::m_toolRun2
ToolHandle< Trig::IIParticleRetrievalTool > m_toolRun2
Definition: NavigationTesterAlg.h:28
python.compressB64.c
def c
Definition: compressB64.py:93
xAOD::operator<<
std::ostream & operator<<(std::ostream &out, const std::pair< FIRST, SECOND > &pair)
Helper print operator.
Definition: RDataSource.cxx:53