ATLAS Offline Software
Loading...
Searching...
No Matches
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
13namespace 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);
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,
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
178 const R3MatchingTool::chainInfo_t &R3MatchingTool::getChainInfo(const std::string &chain) const
179 {
180 std::lock_guard<std::mutex> guard(m_chainInfoMutex);
181 auto cacheItr = m_chainInfoCache.find(chain);
182 if (cacheItr == m_chainInfoCache.end())
183 {
184 chainInfo_t info;
185 for (const ChainNameParser::LegInfo &legInfo : ChainNameParser::HLTChainInfo(chain))
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
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_ERROR(x)
#define ATH_MSG_WARNING(x)
#define ATH_MSG_DEBUG(x)
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
Helper class that provides access to information about individual legs.
stored_index_type persIndex() const
Return the index of the link.
sgkey_t persKey() const
Return the SG key that we reference, as a hash.
std::vector< std::string > getListOfTriggers() const
ToolHandle< Trig::IMatchScoringTool > m_scoreTool
virtual StatusCode initialize() override
Dummy implementation of the initialisation function.
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
ToolHandle< TrigDecisionTool > m_trigDecTool
const chainInfo_t & getChainInfo(const std::string &chain) const
R3MatchingTool(const std::string &name)
virtual bool match(const std::vector< const xAOD::IParticle * > &recoObjects, const std::string &chain, double matchThreshold, bool rerun) const override
multi-object trigger matching
std::pair< multInfo_t, typeInfo_t > chainInfo_t
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
elec/gamma data class.
Definition egamma.h:58
Class providing the definition of the 4-vector interface.
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.
@ UniqueObjects
Do not allow any repeated objects.
The common trigger namespace for trigger analysis tools.
ObjectType
Type of objects that have a representation in the xAOD EDM.
Definition ObjectType.h:32
@ Photon
The object is a photon.
Definition ObjectType.h:47
@ Other
An object not falling into any of the other categories.
Definition ObjectType.h:34
@ CaloCluster
The object is a calorimeter cluster.
Definition ObjectType.h:39
@ Electron
The object is an electron.
Definition ObjectType.h:46
Egamma_v1 Egamma
Definition of the current "egamma version".
Definition Egamma.h:17
DataVector< IParticle > IParticleContainer
Simple convenience declaration of IParticleContainer.
Struct containing information on each leg of a chain.
Helper to keep a Decision object, ElementLink and ActiveState (with respect to some requested ChainGr...
Definition LinkInfo.h:22