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 
84  // We assume that the navigation is ultimately a set of element links
85  // We're comparing two types of navigation but they should both point to the same
86  // objects.
87  // We don't care about the order of the combinations, or the order within the
88  // combinations, we just care that they are the same. Therefore, we can convert the
89  // vectors to sets and just look at the differences between them
90  CombinationsVector vecCombinationsRun2;
91  ATH_MSG_DEBUG("###### checking features of CHAIN " << chain);
92  ATH_CHECK(m_toolRun2->retrieveParticles(vecCombinationsRun2, chain));
93  auto combsRun2 = vectorToSet(vecCombinationsRun2);
94  ATH_MSG_DEBUG("Run 2 size " << combsRun2.size());
95  for (auto& c : combsRun2 ) {
97  }
98  CombinationsVector vecCombinationsRun3;
99  ATH_CHECK(m_toolRun3->retrieveParticles(vecCombinationsRun3, chain));
100  auto combsRun3 = vectorToSet(vecCombinationsRun3);
101  ATH_MSG_DEBUG("Run 3 size " << combsRun3.size());
102 
103  if (combinationsEmpty(vecCombinationsRun2) and combinationsEmpty(vecCombinationsRun3)) {
104  ATH_MSG_DEBUG("Both, Run2 and Run3 combinations are effectively empty");
105  continue;
106  }
107 
108 
109  for (auto& c : combsRun3 ) {
110  ATH_MSG_DEBUG(c);
111  }
112  if ( std::regex_match(chain, SpecialCases::gammaXeChain) ) {
114  } else {
115  if ( m_verifyCombinationsSize ) {
116  ATH_CHECK(verifyCombinationsSize(vecCombinationsRun2, vecCombinationsRun3, chain));
117  }
118  if ( m_verifyCombinations ) {
119  ATH_CHECK(verifyCombinationsContent(combsRun2, combsRun3, chain));
120  }
121  }
122 
123  ATH_MSG_DEBUG("Verified chain " << chain);
124  }
125  return StatusCode::SUCCESS;
126  }
127 
129  const auto &run3 = m_tdtRun3->features<xAOD::IParticleContainer>(chain);
130  std::set<const xAOD::IParticle*> particlesRun3;
131  for ( auto l: run3) {
132  if ( l.link.isValid() )
133  particlesRun3.insert(*(l.link));
134  }
135 
136  CombinationsVector vecCombinationsRun2;
137  ATH_CHECK(m_toolRun2->retrieveParticles(vecCombinationsRun2, chain));
138  std::set<const xAOD::IParticle*> particlesRun2;
139  for ( auto& comb: vecCombinationsRun2) {
140  for ( auto el: comb) {
141  particlesRun2.insert(el);
142  }
143  }
144 
145  for ( auto f2: particlesRun2 ) {
146  bool found=false;
147  for ( auto f3: particlesRun3 ) {
148  ATH_MSG_DEBUG("Serial set of features " << f3 );
149  if ( f2 == f3)
150  found = true;
151  }
152  if ( not found ) {
153  ATH_MSG_ERROR("Missing feature in Run 3 that is present in Run 2 " << f2 << " chain " << chain << " enable DEBUG to see more details" );
154  if ( m_failOnDifference ) {
155  return StatusCode::FAILURE;
156  }
157  }
158  }
159  return StatusCode::SUCCESS;
160  }
161 
162 
164  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
165  ATH_MSG_WARNING("Issue in combination sizes for chain " << chain
166  << " using Run 2 navigation " << run2.size()
167  << " Run 3 navigation " << run3.size());
168  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");
169  if ( m_failOnDifference ) {
170  return StatusCode::FAILURE;
171  }
172  }
173  return StatusCode::SUCCESS;
174  }
175 
177  // compare combinations
178  bool isSubset = std::includes(run3.begin(), run3.end(), run2.begin(), run2.end());
179  if (run2 != run3)
180  {
181  ATH_MSG_WARNING("Difference in combinations between Run2 and Run3 format for chain: " << chain << " parsed multiplicities " << ChainNameParser::multiplicities(chain));
182  ATH_MSG_WARNING("Run2 combs: " << run2);
183  ATH_MSG_WARNING("Run3 combs: " << run3);
184  }
185  if (not isSubset)
186  {
187  ATH_MSG_WARNING("NOT PASSED not isSubset failed, Run2 is not a subset of Run3 for chain: " << chain << " parsed multiplicities " << ChainNameParser::multiplicities(chain));
188  ATH_MSG_WARNING("Run2 combs: " << run2);
189  ATH_MSG_WARNING("Run3 combs: " << run3);
190  if ( m_failOnDifference ) {
191  return StatusCode::FAILURE;
192  }
193  }
194 
195  for ( auto& combRun2: run2 ) {
196  bool foundMatching = false;
197  for ( auto& combRun3 : run3 ) {
198  ATH_MSG_DEBUG("Available Run 2 combinations: " );
199  for ( auto& c: combRun2 ){
200  ATH_MSG_DEBUG(" " << c );
201  }
202  ATH_MSG_DEBUG("Available Run 3 combinations: " );
203  for ( auto& c: combRun3 ){
204  ATH_MSG_DEBUG(" " << c );
205  }
206  ATH_MSG_DEBUG("COMPARISON combRun2 == combRun3 are " << ( combRun2 == combRun3 ? "identical" : "distinct"));
207  if ( combRun2 == combRun3 ) {
208  ATH_MSG_DEBUG("Found matching combinations, run2 " << combRun2
209  << " run3 " << combRun3 );
210  foundMatching = true;
211  break;
212  }
213  }
214  if ( not foundMatching ) {
215  ATH_MSG_WARNING("Specific combination for chain " << chain << " can not be found in Run 3");
216  ATH_MSG_WARNING("Run 2 combination: " << combRun2 );
217  ATH_MSG_WARNING("Available Run 3 combinations: " );
218  for ( auto& c: run3 ){
219  ATH_MSG_WARNING(" " << c );
220  }
221  ATH_MSG_ERROR("When checking combinations in details found differences, (enable WARNING message for more details)");
222  if ( m_failOnDifference ) {
223  return StatusCode::FAILURE;
224  }
225  }
226  }
227  return StatusCode::SUCCESS;
228  }
229 
231  size_t counter = 0;
232  for ( auto outerc: combs )
233  counter += outerc.size();
234  return counter == 0;
235  }
236 
237 } //> end namespace Trig
238 
239 
NavigationTesterAlg.h
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
Trig::NavigationTesterAlg::m_tdtRun3
PublicToolHandle< Trig::TrigDecisionTool > m_tdtRun3
Definition: NavigationTesterAlg.h:25
ChainNameParser.h
Trig::NavigationTesterAlg::m_verifyCombinations
Gaudi::Property< bool > m_verifyCombinations
Definition: NavigationTesterAlg.h:40
python.PerfMonSerializer.p
def p
Definition: PerfMonSerializer.py:743
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: CaloTowerVecMon.h:44
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:176
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
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:230
beamspotPlotBcids.chain
chain
Definition: beamspotPlotBcids.py:442
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:40
SpecialCases::gammaXeChain
const std::regex gammaXeChain
Definition: SpecialCases.h:8
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
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:128
ret
T ret(T t)
Definition: rootspy.cxx:260
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:163
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.
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
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:192
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
beamspotCoolDiff.l
l
Definition: beamspotCoolDiff.py:354
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
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