ATLAS Offline Software
Loading...
Searching...
No Matches
MatchFromCompositeTool.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8#include "CxxUtils/crc64.h"
9#include <format>
10#include <stdexcept>
11
12#ifdef XAOD_STANDALONE
13namespace {
14 SG::sgkey_t hashContainer(const std::string &container, CLID clid)
15 {
16 static const SG::sgkey_t sgkey_t_max = (static_cast<SG::sgkey_t>(1) << 30) - 1;
17 return CxxUtils::crc64addint(CxxUtils::crc64(container), clid) & sgkey_t_max;
18 }
19}
20#endif
21
22namespace Trig {
24 asg::AsgTool(name)
25 {
26 declareProperty("MatchShallow", m_matchShallow,
27 "Whether to check if two objects are shallow copies of each other. "
28 "If this is not true then pointer equality will be used.");
29 declareProperty("DRThreshold", m_drThreshold,
30 "If greater than 0 then use the DR between two objects to check if "
31 "they are the same object.");
32 declareProperty("InputPrefix", m_inputPrefix="TrigMatch_",
33 "The input prefix to expect at the beginning of the TrigComposite "
34 "container names.");
35#ifdef XAOD_STANDALONE
36 declareProperty("RemapBrokenLinks", m_remapBrokenLinks,
37 "Whether to remap element links which are broken in some derivations for AnalysisBase");
38 declareProperty("RemapContainers", m_remapContainers,
39 "Containers whose links need remapping");
40 declareProperty("RemapCLIDs", m_remapCLIDs, "CLIDs for those containers");
41#endif
42 }
43
45
47 ATH_MSG_INFO( "initializing " << name() );
48#ifdef XAOD_STANDALONE
49 ATH_MSG_INFO("Remap broken links? " << m_remapBrokenLinks);
50 if (m_remapBrokenLinks)
51 {
52 if (m_remapContainers.size() != m_remapCLIDs.size())
53 {
54 ATH_MSG_ERROR("Number of containers and CLIDs to remap do not match!");
55 return StatusCode::FAILURE;
56 }
58 for (std::size_t idx = 0; idx < m_remapContainers.size(); ++idx)
59 {
60 const std::string &name = m_remapContainers[idx];
61 m_keyRemap[hashContainer(name, iparticleCLID)] = hashContainer(name, m_remapCLIDs[idx]);
62 }
63 ATH_MSG_INFO("Remap: ");
64 for (const auto &p : m_keyRemap)
65 ATH_MSG_INFO("\t" << p.first << " -> " << p.second);
66
67 }
68#endif
69 return StatusCode::SUCCESS;
70 }
71
73 const xAOD::IParticle& recoObject,
74 std::string_view chain,
75 double, bool) const
76 {
77 return match({&recoObject}, chain);
78 }
79
81 const std::vector<const xAOD::IParticle*>& recoObjects,
82 std::string_view chain,
83 double, bool) const
84 {
85 std::string containerName = m_inputPrefix;
86 containerName.append(chain);
87 // We have to replace '.' characters with '_' characters so that these are
88 // valid container names...
89 std::replace(containerName.begin(), containerName.end(), '.', '_');
90 const xAOD::TrigCompositeContainer* composites(nullptr);
91 if (evtStore()->retrieve(composites, containerName).isFailure() ){
92 ATH_MSG_ERROR("Failed to retrieve composite container for chain "<< chain);
93 ATH_MSG_ERROR("Please check your derivation to see if the container is there");
94 ATH_MSG_ERROR("This likely means the trigger is not in your file's menu");
95 throw std::runtime_error(
96 std::format("Failed to retrieve composite corresponding to chain {}",chain));
97 }
98 const constAcc_t<vecLink_t<xAOD::IParticleContainer>> accMatched("TrigMatchedObjects");
99 for (const xAOD::TrigComposite* composite : *composites) {
100 if (testCombination(accMatched(*composite), recoObjects) )
101 return true;
102 }
103 // If we get here then none of the online combinations worked
104 return false;
105 }
106
108 const vecLink_t<xAOD::IParticleContainer>& onlineLinks,
109 const std::vector<const xAOD::IParticle*>& offline) const
110 {
111 // We need to make sure we don't allow two offline particles to match to the
112 // same online particle, so we copy the vector so we can erase objects if
113 // necessary. Dereference the links at the same time.
114 std::vector<const xAOD::IParticle*> online;
115 online.reserve(onlineLinks.size() );
116 for (const ElementLink<xAOD::IParticleContainer>& link : onlineLinks)
117 // Skip invalid links - these are usually objects that have been removed
118 // by derivation framework level thinning. Going by the logic that we just
119 // need a match for all the offline particles provided rather than for the
120 // trigger particles implies that we should allow a combination that has
121 // had some of its members removed.
122 if (link.isValid() )
123 online.push_back(*link);
124#ifdef XAOD_STANDALONE
125 else if (m_remapBrokenLinks)
126 {
127 auto itr = m_keyRemap.find(link.persKey());
128 if (itr != m_keyRemap.end())
129 online.push_back(*ElementLink<xAOD::IParticleContainer>(itr->second, link.index()));
130 }
131#endif
132 // I will follow the way the current tool works and match even if there are
133 // fewer reco objects than trigger objects
134 for (const xAOD::IParticle* offlinePart : offline) {
135 bool isMatched = false;
136 for (auto itr = online.begin(); itr != online.end(); ++itr) {
137 if (areTheSame(*offlinePart, **itr) ) {
138 // Remove this online particle from consideration
139 online.erase(itr);
140 isMatched = true;
141 break;
142 }
143 }
144 if (!isMatched)
145 // We've found an offline particle we couldn't match so the whole
146 // combination doesn't match.
147 return false;
148 }
149 // To reach this point every offline particle must have found a match.
150 return true;
151 }
152
154 const xAOD::IParticle& lhs,
155 const xAOD::IParticle& rhs) const
156 {
157 // If we've been given a dR threshold > 0 then we just use that.
158 if (m_drThreshold > 0) {
159 return xAOD::P4Helpers::deltaR(lhs, rhs, false) < m_drThreshold;
160 }
161 else if (m_matchShallow) {
162 static const SG::AuxElement::ConstAccessor<
163 ElementLink<xAOD::IParticleContainer>> accOOL("originalObjectLink");
164 // For now assume that we've got a shallow copy iff this is available
165 const xAOD::IParticle* lhsOrig =
166 accOOL.isAvailable(lhs) ? *accOOL(lhs) : &lhs;
167 const xAOD::IParticle* rhsOrig =
168 accOOL.isAvailable(rhs) ? *accOOL(rhs) : &rhs;
169 return lhsOrig == rhsOrig;
170 }
171 else {
172 // Otherwise just use pointer equality
173 return &lhs == &rhs;
174 }
175 }
176
177} //> end namespace Trig
#define ATH_MSG_ERROR(x)
#define ATH_MSG_INFO(x)
uint32_t CLID
The Class ID type.
Gaudi::Details::PropertyBase & declareProperty(Gaudi::Property< T, V, H > &t)
ServiceHandle< StoreGateSvc > & evtStore()
std::map< SG::sgkey_t, SG::sgkey_t > m_keyRemap
~MatchFromCompositeTool() override
Default destructor.
bool match(const xAOD::IParticle &recoObject, std::string_view chain, double=0.1, bool=false) const override
Match a single object.
MatchFromCompositeTool(const std::string &name)
Standard constructor.
float m_drThreshold
If greater than 0 then will skip the above check and just check that DR between the two particles is ...
std::vector< ElementLink< T > > vecLink_t
StatusCode initialize() override
Initialise the tool.
bool testCombination(const vecLink_t< xAOD::IParticleContainer > &onlineLinks, const std::vector< const xAOD::IParticle * > &offline) const
Test a combination of offline objects against a combination of online objects.
SG::AuxElement::ConstAccessor< T > constAcc_t
Helper typedefs for accessors/decorators, vectors of ele links.
bool areTheSame(const xAOD::IParticle &lhs, const xAOD::IParticle &rhs) const
Check if two particles are the same.
std::string m_inputPrefix
The prefix to expect at the front of the trig composite container name.
bool m_matchShallow
Allow matching shallow copy to shallow copy.
AsgTool(const std::string &name)
Constructor specifying the tool instance's name.
Definition AsgTool.cxx:58
Class providing the definition of the 4-vector interface.
XAOD_AUXDATA_DEPRECATED bool isAvailable(const std::string &name, const std::string &clsname="") const
Check if a user property is available for reading or not.
A crc-64 implementation, using pclmul where possible.
uint64_t crc64(const CRCTable &table, const char *data, size_t data_len)
Find the CRC-64 of a string,.
Definition crc64.cxx:696
uint64_t crc64addint(uint64_t crc, uint64_t x)
Extend a previously-calculated CRC to include an int.
Definition crc64.cxx:732
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
The common trigger namespace for trigger analysis tools.
double deltaR(double rapidity1, double phi1, double rapidity2, double phi2)
from bare bare rapidity,phi
TrigCompositeContainer_v1 TrigCompositeContainer
Declare the latest version of the container.
TrigComposite_v1 TrigComposite
Declare the latest version of the class.