ATLAS Offline Software
Loading...
Searching...
No Matches
TrigComposite_v1.icc
Go to the documentation of this file.
1// Dear emacs, this is -*- c++ -*-
2
3/*
4 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
5*/
6
7#ifndef XAODTRIGGER_VERSIONS_TRIGCOMPOSITE_V1_ICC
8#define XAODTRIGGER_VERSIONS_TRIGCOMPOSITE_V1_ICC
9
10// System include(s):
11#include <iostream>
12#include <stdexcept>
13
14// xAOD include(s):
15#include "AthContainers/tools/CurrentEventStore.h"
16#include "AthContainers/DataVector.h"
17#include "AthContainers/normalizedTypeinfoName.h"
18#include "AthContainers/Accessor.h"
19#include "xAODCore/CLASS_DEF.h"
20
21// In "standalone mode" xAOD::IParticleContainer doesn't have a CLID
22// defined for it. But this code requires one to be set.
23//
24// The following is incredibly ugly, but this is the best that I could
25// come up with on short notice. Note that the CLID value is copy-pasted
26// from the IParticleContainer.h header.
27#include "xAODBase/IParticleContainer.h"
28#ifdef XAOD_STANDALONE
29CLASS_DEF( xAOD::IParticleContainer, 1241842700, 1 )
30#endif // XAOD_STANDALONE
31
32namespace xAOD {
33
34 template< typename TYPE >
35 bool TrigComposite_v1::hasDetail( const std::string& name ) const {
36
37 // Object used to check for the existence of an object:
38 ConstAccessor< TYPE > acc( name );
39
40 // Use the Accessor object for the check:
41 return acc.isAvailable( *this );
42 }
43
44 template< typename TYPE >
45 bool TrigComposite_v1::setDetail( const std::string& name, const TYPE& value ) {
46 // It should be pretty strange if this should fail:
47 SG::Accessor< TYPE > acc( name );
48 try {
49 acc( *this ) = value;
50 } catch(const std::exception& exc) {
51 std::cerr << "xAOD::TrigComposite_v1::setDetail ERROR Internal logic error found: [" << exc.what() << "]" << std::endl;
52 return false;
53 }
54 // Return gracefully:
55 return true;
56 }
57
58 template< typename TYPE >
59 bool TrigComposite_v1::getDetail( const std::string& name, TYPE& value) const {
60 // Object used to access the auxiliary data:
61 ConstAccessor< TYPE > acc( name );
62
63 if( ! acc.isAvailable( *this ) ) {
64 return false;
65 }
66 value = acc( *this );
67 return true;
68 }
69
70 template< typename TYPE >
71 TYPE TrigComposite_v1::getDetail( const std::string& name ) const {
72 ConstAccessor< TYPE > acc( name );
73 return acc( *this );
74 }
75
76 template< class CONTAINER >
77 bool
78 TrigComposite_v1::setObjectLink( const std::string& name,
79 const ElementLink< CONTAINER >& link ) {
80
81 // Check link has valid persistent state, i.e. hash key is not
82 // zero, otherwise attempting to access its string key will seg
83 // fault later, e.g. in remapping.
84 if( link.key() == 0 ) {
85 std::cerr << "xAOD::TrigComposite_v1::setObjectLink ERROR "
86 << "link has invalid key hash of zero" << std::endl;
87 return false;
88 }
89
90 if( ! link.isValid() ) {
91 std::cerr << "xAOD::TrigComposite_v1::setObjectLink ERROR "
92 << "link is not valid" << std::endl;
93 return false;
94 }
95
96 // Do different things depending on whether this variable already
97 // exists or not:
98 if( hasObjectLink( name ) ) {
99 // Find the right object:
100 const std::vector< std::string >& names = linkColNames();
101 for( size_t i = 0; i < names.size(); ++i ) {
102 if( names[ i ] != name ) continue;
103 // Extract the information out of the ElementLink:
104 linkColKeysNC()[ i ] = link.key();
105 linkColIndicesNC()[ i ] = link.index();
106 linkColClidsNC()[ i ] = ClassID_traits< CONTAINER >::ID();
107 // We're done:
108 return true;
109 }
110 // Some error happened...
111 std::cerr << "xAOD::TrigComposite_v1::setObjectLink ERROR Internal "
112 << "logic error found" << std::endl;
113 return false;
114 } else {
115 // Add a new object:
116 linkColNamesNC().push_back( name );
117 linkColKeysNC().push_back( link.key() );
118 linkColIndicesNC().push_back( link.index() );
119 linkColClidsNC().push_back( ClassID_traits< CONTAINER >::ID() );
120 // And we're done:
121 return true;
122 }
123 }
124
125 template< class CONTAINER >
126 ElementLink< CONTAINER >
127 TrigComposite_v1::objectLink( const std::string& name ) const {
128
129 // Retrieve current store once (would be better to pass EventContext everywhere)
130 auto sg = SG::CurrentEventStore::store();
131
132 // Find the right object:
133 const std::vector< std::string >& names = linkColNames();
134 for( size_t i = 0; i < names.size(); ++i ) {
135 if( names[ i ] != name ) continue;
136 checkTypes< CONTAINER >(linkColClids()[ i ], name);
137 ElementLink< CONTAINER > link( linkColKeys()[ i ],
138 linkColIndices()[ i ],
139 sg );
140
141 if (link.isValid()) {
142 return link;
143 }
144
145 if (isRemapped()) {
146 return ElementLink< CONTAINER >( linkColKeysRemap()[ i ],
147 linkColIndicesRemap()[ i ],
148 sg );
149 }
150
151 return link;
152 }
153
154 // We didn't find the link. :-(
155 throw std::runtime_error( "xAOD::TrigComposite::objectLink: No link "
156 "name \"" + name + "\" found" );
157 }
158
159 template< class OBJECT >
160 const OBJECT* TrigComposite_v1::object( const std::string& name ) const {
161
162 // Check if the link exists:
163 if( ! hasObjectLink( name ) ) {
164 return nullptr;
165 }
166
167 // Retrieve current store once (would be better to pass EventContext everywhere)
168 auto sg = SG::CurrentEventStore::store();
169
170 // Now look for it:
171 const std::vector< std::string >& names = linkColNames();
172 for( size_t i = 0; i < names.size(); ++i ) {
173 if( names[ i ] != name ) continue;
174 // Check that it is of the right type:
175 checkTypes< DataVector< OBJECT > >(linkColClids()[ i ], name);
176 // Create a temporary ElementLink:
177 ElementLink< DataVector< OBJECT > > link( linkColKeys()[ i ],
178 linkColIndices()[ i ],
179 sg );
180 if( link.isValid() ) {
181 return *link;
182 }
183
184 if (isRemapped()) {
185 link = ElementLink< DataVector< OBJECT > >( linkColKeysRemap()[ i ],
186 linkColIndicesRemap()[ i ],
187 sg );
188 if( link.isValid() ) {
189 return *link;
190 }
191 }
192
193 return nullptr;
194 }
195
196 // There was an internal error. :-(
197 std::cerr << "xAOD::TrigComposite_v1::object ERROR Internal error "
198 << "detected" << std::endl;
199 return nullptr;
200 }
201
202 template< class CONTAINER >
203 bool
204 TrigComposite_v1::addObjectCollectionLink( const std::string& collectionName,
205 const ElementLink< CONTAINER >& link ) {
206
207 // No method currently provided to update or check for uniqueness of a link
208 // being added to a container.
209
210 // Add a new object (unless it would duplicate an existing one):
211 const std::string mangledName = collectionName + s_collectionSuffix;
212 if (!hasObjectLinkExact(mangledName, link.key(), link.index(), ClassID_traits< CONTAINER >::ID())) {
213 linkColNamesNC().push_back( std::move(mangledName) );
214 linkColKeysNC().push_back( link.key() );
215 linkColIndicesNC().push_back( link.index() );
216 linkColClidsNC().push_back( ClassID_traits< CONTAINER >::ID() );
217 }
218 return true;
219 }
220
221 template< class CONTAINER >
222 bool
223 TrigComposite_v1::addObjectCollectionLinks( const std::string& collectionName,
224 const std::vector<ElementLink< CONTAINER >>& links ) {
225 // Add all links
226 for (const ElementLink< CONTAINER >& link : links ) {
227 addObjectCollectionLink( collectionName, link );
228 }
229 return true;
230 }
231
232 template< class CONTAINER >
233 std::vector<ElementLink< CONTAINER >>
234 TrigComposite_v1::objectCollectionLinks( const std::string& collectionName ) const {
235 std::vector<ElementLink< CONTAINER >> links;
236 const std::string mangledName = collectionName + s_collectionSuffix;
237
238 // Retrieve current store once (would be better to pass EventContext everywhere)
239 auto sg = SG::CurrentEventStore::store();
240
241 const std::vector< std::string >& names = linkColNames();
242 for( size_t i = 0; i < names.size(); ++i ) {
243 if( names[ i ] != mangledName ) continue;
244 // Check that it is of the right type:
245 checkTypes< CONTAINER >(linkColClids()[ i ], collectionName);
246 // Construct and add the link:
247 ElementLink< CONTAINER > link(linkColKeys()[ i ],
248 linkColIndices()[ i ],
249 sg);
250 if (link.isValid()) {
251 links.push_back( link );
252 } else if (isRemapped()) {
253 link = ElementLink< CONTAINER >(linkColKeysRemap()[ i ],
254 linkColIndicesRemap()[ i ],
255 sg);
256 links.push_back( link );
257 } else {
258 links.push_back( link );
259 }
260 }
261 return links;
262 }
263
264 template< class CONTAINER >
265 std::vector<std::string> TrigComposite_v1::getObjectNames() const {
266 return getObjectNames(ClassID_traits< CONTAINER >::ID());
267 }
268
269 template< class CONTAINER >
270 std::vector<std::string> TrigComposite_v1::getObjectCollectionNames() const {
271 return getObjectCollectionNames(ClassID_traits< CONTAINER >::ID());
272 }
273
274 template<class CONTAINER>
275 void TrigComposite_v1::checkTypes(const uint32_t storedCLID, const std::string& name) const {
276 if (ClassID_traits< CONTAINER >::ID() == ClassID_traits< xAOD::IParticleContainer >::ID()) {
277 if (!derivesFromIParticle(storedCLID)) {
278 throw ExcNotIParticleContainer( "xAOD::TrigComposite::checkTypes: "
279 "Cannot retrieve \"" + name + "\" as an IParticle");
280 }
281 } else if (ClassID_traits< CONTAINER >::ID() != storedCLID) {
282 const std::string typeName = SG::normalizedTypeinfoName( typeid( CONTAINER ) );
283 throw std::runtime_error( "xAOD::TrigComposite::checkTypes: "
284 "Wrong type (" + typeName + ") requested "
285 "for name \"" + name + "\"" );
286 }
287 }
288
289} // namespace xAOD
290
291#endif // XAODTRIGGER_VERSIONS_TRIGCOMPOSITE_V1_ICC