ATLAS Offline Software
R3MatchingTool.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
9 #include "xAODEgamma/Egamma.h"
10 #include <numeric>
11 #include <algorithm>
12 
13 namespace Trig
14 {
15 
16  R3MatchingTool::R3MatchingTool(const std::string &name) : asg::AsgTool(name)
17  {
18  m_trigDecTool.setTypeAndName("Trig::TrigDecisionTool/TrigDecisionTool");
19  declareProperty("TrigDecisionTool", m_trigDecTool, "The trigger decision tool");
20  }
21 
23 
25  {
26  ATH_CHECK(m_trigDecTool.retrieve());
27  ATH_CHECK(m_scoreTool.retrieve());
28  return StatusCode::SUCCESS;
29  }
30 
32  const std::vector<const xAOD::IParticle *> &recoObjects,
33  const std::string &chain,
34  double matchThreshold,
35  bool rerun) const
36  {
37  if (recoObjects.size() == 0)
38  // If there are no reco objects, the matching is trivially true
39  return true;
40  // Make the LinkInfo type less verbose
42  using VecLinkInfo_t = std::vector<IPartLinkInfo_t>;
43  // TODO - detect if we're looking at run 3 data.
44  // If we are, then setting rerun to true should give a warning as it no
45  // longer makes sense for run 3
46 
47  // In what follows, the same comparisons between reco and trigger objects will done
48  // fairly frequently. As these include DR checks we want to minimise how often we do these
49  // Therefore we keep track of any comparisons that we've already done
50  // There is one map per input reco object, and then each map entry is the keyed on information
51  // extracted from the element link
52  std::vector<std::map<std::pair<uint32_t, uint32_t>, bool>> cachedComparisons(recoObjects.size());
53 
54  // Note that the user can supply a regex pattern which matches multiple chains
55  // We should return true if any individual chain matches
56  const Trig::ChainGroup *chainGroup = m_trigDecTool->getChainGroup(chain);
57  for (const std::string &chainName : chainGroup->getListOfTriggers())
58  {
59  const chainInfo_t &chainInfo = getChainInfo(chainName);
60  if (!m_trigDecTool->isPassed(chainName, rerun ? TrigDefs::Physics | TrigDefs::allowResurrectedDecision : TrigDefs::Physics))
61  {
62  ATH_MSG_DEBUG("Chain " << chainName << " did not pass");
63  continue;
64  }
65  ATH_MSG_DEBUG("Chain " << chainName << " passed");
66  VecLinkInfo_t features = m_trigDecTool->features<xAOD::IParticleContainer>(chainName);
67  // See if we have any that have invalid links. This is a sign that the
68  // input file does not contain the required information and should be seen
69  // as reason for a job failure
70  for (IPartLinkInfo_t &linkInfo : features)
71  {
72  if (!linkInfo.isValid())
73  {
74  ATH_MSG_ERROR("Chain " << chainName << " has invalid link info!");
75  throw std::runtime_error("Bad link info");
76  }
77  }
78  // Now we have to build up combinations
79  // TODO - right now we use a filter that passes everything that isn't pointer-equal.
80  // This will probably need to be fixed to something else later - at least the unique RoI filter
82  chainName,
83  features,
84  chainInfo.first,
86  // Warn once per call if one of the chain groups is too small to match anything
87  if (combinations.size() < recoObjects.size())
88  {
90  "Chain " << chainName << " (matching pattern " << chain << ") has too few objects ("
91  << combinations.size() << ") to match the number of provided reco objects (" << recoObjects.size() << ")");
92  continue;
93  }
94  // Now we iterate through the available combinations
95  for (const VecLinkInfo_t &combination : combinations)
96  {
97  // Prepare the index vector
98  std::vector<std::size_t> onlineIndices(combination.size());
99  std::iota(onlineIndices.begin(), onlineIndices.end(), 0);
100  do
101  {
102  bool match = true;
103  for (std::size_t recoIdx = 0; recoIdx < recoObjects.size(); ++recoIdx)
104  {
105  std::size_t onlineIdx = onlineIndices[recoIdx];
106  if (!matchObjects(
107  recoObjects[recoIdx],
108  combination[onlineIdx].link,
109  chainInfo.second[onlineIdx],
110  cachedComparisons[recoIdx],
111  matchThreshold))
112  {
113  match = false;
114  break;
115  }
116  }
117  if (match)
118  return true;
119  } while (std::next_permutation(onlineIndices.begin(), onlineIndices.end()));
120  }
121  }
122 
123  // If we reach here we've tried all combinations from all chains in the group and none of them matched
124  return false;
125  }
126 
128  const xAOD::IParticle &recoObject,
129  const std::string &chain,
130  double matchThreshold,
131  bool rerun) const
132  {
133  std::vector<const xAOD::IParticle *> tmpVec{&recoObject};
134  return match(tmpVec, chain, matchThreshold, rerun);
135  }
136 
138  const xAOD::IParticle *reco,
139  const ElementLink<xAOD::IParticleContainer> &onlineLink,
140  xAODType::ObjectType onlineType,
141  std::map<std::pair<uint32_t, uint32_t>, bool> &cache,
142  double scoreThreshold) const
143  {
144  if (!onlineLink.isValid())
145  {
146  ATH_MSG_WARNING("Invalid element link!");
147  return false;
148  }
149  std::pair<uint32_t, uint32_t> linkIndices(onlineLink.persKey(), onlineLink.persIndex());
150  auto cacheItr = cache.find(linkIndices);
151  if (cacheItr == cache.end())
152  {
153  const xAOD::IParticle *online = *onlineLink;
154  ATH_MSG_DEBUG("Match online " << onlineType << " to offline " << reco->type());
155  bool match = onlineType == reco->type();
156  if (onlineType == xAOD::Type::CaloCluster && (reco->type() == xAOD::Type::Electron || reco->type() == xAOD::Type::Photon))
157  {
158  // Calo cluster is a special case - some of the egamma chains can return these (the etcut chains)
159  // In these cases we need to match this against the caloCluster object contained in electrons or photons
160  const xAOD::Egamma *egamma = dynamic_cast<const xAOD::Egamma *>(reco);
161  if (!egamma)
162  // this should never happen
163  throw std::runtime_error("Failed to cast to egamma object");
164  const xAOD::IParticle *cluster = egamma->caloCluster();
165  if (cluster)
166  reco = cluster;
167  else
168  ATH_MSG_WARNING("Cannot retrieve egamma object's primary calorimeter cluster, will match to the egamma object");
169  match = true;
170  }
171  if (match)
172  match = m_scoreTool->score(*online, *reco) < scoreThreshold;
173  cacheItr = cache.insert(std::make_pair(linkIndices, match)).first;
174  }
175  return cacheItr->second;
176  }
177 
179  {
180  std::lock_guard<std::mutex> guard(m_chainInfoMutex);
181  auto cacheItr = m_chainInfoCache.find(chain);
182  if (cacheItr == m_chainInfoCache.end())
183  {
186  {
187  const xAODType::ObjectType type = legInfo.type();
188  if (type == xAODType::Other)
189  {
190  // Use 0 to signal that a leg expects no IParticle features
191  info.first.push_back(0);
192  }
193  else
194  {
195  info.first.push_back(legInfo.multiplicity);
196  for (std::size_t idx = 0; idx < legInfo.multiplicity; ++idx)
197  info.second.push_back(type);
198  }
199  }
200  cacheItr = m_chainInfoCache.insert(std::make_pair(chain, std::move(info))).first;
201  }
202  return cacheItr->second;
203  }
204 
205 } // namespace Trig
grepfile.info
info
Definition: grepfile.py:38
TrigCompositeUtils::buildCombinations
Combinations buildCombinations(const std::string &chainName, const std::vector< LinkInfo< xAOD::IParticleContainer >> &features, const std::vector< std::size_t > &legMultiplicities, const std::function< bool(const std::vector< LinkInfo< xAOD::IParticleContainer >> &)> &filter)
Produce the combinations for a set of features.
Definition: TrigCompositeUtilsRoot.cxx:800
xAOD::Electron
Electron_v1 Electron
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Electron.h:17
ChainNameParser.h
runLayerRecalibration.chain
chain
Definition: runLayerRecalibration.py:175
Trig
The common trigger namespace for trigger analysis tools.
Definition: LArCellMonAlg.h:33
AthCommonDataStore< AthCommonMsg< AlgTool > >::declareProperty
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T > &t)
Definition: AthCommonDataStore.h:145
TrigCompositeUtils::FilterType::UniqueObjects
@ UniqueObjects
Do not allow any repeated objects.
Trig::R3MatchingTool::m_trigDecTool
ToolHandle< TrigDecisionTool > m_trigDecTool
Definition: R3MatchingTool.h:45
ChainNameParser::HLTChainInfo
Helper class that provides access to information about individual legs.
Definition: ChainNameParser.h:82
asg
Definition: DataHandleTestTool.h:28
xAOD::Egamma_v1
Definition: Egamma_v1.h:56
xAOD::IParticle
Class providing the definition of the 4-vector interface.
Definition: Event/xAOD/xAODBase/xAODBase/IParticle.h:41
xAOD::CaloCluster
CaloCluster_v1 CaloCluster
Define the latest version of the calorimeter cluster class.
Definition: Event/xAOD/xAODCaloEvent/xAODCaloEvent/CaloCluster.h:19
egamma
Definition: egamma.h:58
Trig::R3MatchingTool::match
virtual bool match(const std::vector< const xAOD::IParticle * > &recoObjects, const std::string &chain, double matchThreshold, bool rerun) const override
multi-object trigger matching
Definition: R3MatchingTool.cxx:31
Egamma.h
Trig::R3MatchingTool::getChainInfo
const chainInfo_t & getChainInfo(const std::string &chain) const
Definition: R3MatchingTool.cxx:178
TileSynchronizeBch.online
online
Definition: TileSynchronizeBch.py:88
ATH_MSG_ERROR
#define ATH_MSG_ERROR(x)
Definition: AthMsgStreamMacros.h:33
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
IParticleContainer.h
xAODType::Other
@ Other
An object not falling into any of the other categories.
Definition: ObjectType.h:34
Trig::R3MatchingTool::matchObjects
bool matchObjects(const xAOD::IParticle *reco, const ElementLink< xAOD::IParticleContainer > &onlineLink, xAODType::ObjectType onlineType, std::map< std::pair< uint32_t, uint32_t >, bool > &cache, double drThreshold) const
Definition: R3MatchingTool.cxx:137
Trig::R3MatchingTool::R3MatchingTool
R3MatchingTool(const std::string &name)
Definition: R3MatchingTool.cxx:16
ATH_CHECK
#define ATH_CHECK
Definition: AthCheckMacros.h:40
TrigCompositeUtils::Combinations
Definition: Combinations.h:18
DataVector
Derived DataVector<T>.
Definition: DataVector.h:581
Trig::ChainGroup
Definition: ChainGroup.h:51
Trig::R3MatchingTool::m_scoreTool
ToolHandle< Trig::IMatchScoringTool > m_scoreTool
Definition: R3MatchingTool.h:46
name
std::string name
Definition: Control/AthContainers/Root/debug.cxx:221
ChainNameParser::LegInfo
Struct containing information on each leg of a chain.
Definition: ChainNameParser.h:16
xAOD::Photon
Photon_v1 Photon
Definition of the current "egamma version".
Definition: Event/xAOD/xAODEgamma/xAODEgamma/Photon.h:17
python.combo.combinations
def combinations(items, n)
Definition: combo.py:85
Trig::R3MatchingTool::~R3MatchingTool
~R3MatchingTool()
Definition: R3MatchingTool.cxx:22
TrigCompositeUtils::LinkInfo< xAOD::IParticleContainer >
ATH_MSG_WARNING
#define ATH_MSG_WARNING(x)
Definition: AthMsgStreamMacros.h:32
python.CaloScaleNoiseConfig.type
type
Definition: CaloScaleNoiseConfig.py:78
python.TriggerAPI.TriggerAPISession.chainName
chainName
Definition: TriggerAPISession.py:426
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
R3MatchingTool.h
Trig::ChainGroup::getListOfTriggers
std::vector< std::string > getListOfTriggers() const
Definition: ChainGroup.cxx:467
xAODType::ObjectType
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition: ObjectType.h:32
Trig::R3MatchingTool::initialize
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
Definition: R3MatchingTool.cxx:24
Combinations.h
MuonSegmentReaderConfig.reco
reco
Definition: MuonSegmentReaderConfig.py:133
Trig::R3MatchingTool::chainInfo_t
std::pair< multInfo_t, typeInfo_t > chainInfo_t
Definition: R3MatchingTool.h:25