ATLAS Offline Software
Loading...
Searching...
No Matches
HLTEDMCreator.cxx
Go to the documentation of this file.
1
2/*
3 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
4*/
5
6
8#include "HLTEDMCreator.h"
11
19
21
24
37
40
42
44
46
52
64
66
68 const std::string& name,
69 const IInterface* parent )
70 : base_class( type, name, parent ) {}
71
72template<typename T>
73StatusCode HLTEDMCreator::initHandles( const HandlesGroup<T>& handles ) {
74 ATH_CHECK( handles.out.initialize() );
75 if(m_renounceOutputs) { renounceArray( handles.out ); }
76 ATH_CHECK( handles.in.initialize() );
77 renounceArray( handles.in );
78 ATH_CHECK( handles.views.initialize() );
79 renounceArray( handles.views );
80
81 // the case w/o reading from views, both views handles and collection in views should be empty
82 if ( handles.views.empty() ) {
83 ATH_CHECK( handles.in.empty() );
84 } else {
85 // the case with views, for every output we expect an input View and an input collection inside that View
86 ATH_CHECK( handles.out.size() == handles.in.size() );
87 ATH_CHECK( handles.in.size() == handles.views.size() );
88 }
89 return StatusCode::SUCCESS;
90}
91
92template<typename T>
93StatusCode HLTEDMCreator::initAuxKey( const std::vector<SG::VarHandleKey*>& keys ) {
94 // Register Aux keys for all handles to avoid hash collisions (ATR-26386).
95 for (const SG::VarHandleKey* k : keys) {
96 SG::WriteHandleKey<T> auxkey(k->key()+"Aux.");
97 ATH_CHECK( auxkey.initialize() );
98 }
99 return StatusCode::SUCCESS;
100}
101
102
104{
105 if ( m_fixLinks.size() > 0 ) {
106 // Confirm that m_fixLinks is a sub-set of m_TrigCompositeContainer
107 for (const std::string& entry : m_fixLinks) {
108 const bool found = std::any_of(m_TrigCompositeContainer.begin(),
109 m_TrigCompositeContainer.end(), [&](const auto& writeHandleKey) { return writeHandleKey.key() == entry; } );
110 if (!found) {
111 ATH_MSG_ERROR("FixLinks contains the entry " << entry << ", however this is not one of this EDMCreator tool's managed TrigCompositeContainers.");
112 ATH_MSG_ERROR("Configure FixLinks to be a sub-set of TrigCompositeContainer");
113 return StatusCode::FAILURE;
114 }
115 }
116 // Set up the write decorate handles to hold the remapped data
117 for ( const auto& writeHandleKey: m_TrigCompositeContainer ) {
118 const bool doFixLinks = std::any_of(m_fixLinks.begin(), m_fixLinks.end(), [&](const std::string& s) { return s == writeHandleKey.key(); } );
119 if (doFixLinks) {
120 // This writeHandleKey is being included in the element link remapping
121 m_remapLinkColKeys.emplace_back( writeHandleKey.key()+".remap_linkColKeys" );
122 m_remapLinkColIndices.emplace_back( writeHandleKey.key()+".remap_linkColIndices" );
123 }
124 }
125 ATH_CHECK( m_remapLinkColKeys.initialize() ) ;
126 renounceArray( m_remapLinkColKeys ); // This is not strictly necessary however, since we have many of these collection and no consumer for it we can spare scheduler headache renouncing them
127 ATH_CHECK( m_remapLinkColIndices.initialize() );
128 renounceArray( m_remapLinkColIndices );
129 }
130
131 // this section has to appear after the above initialisation of DecorHandles, else the renounce of TrigComposite does not work as expected
132
133#define INIT(__TYPE) \
134 ATH_CHECK( initHandles( HandlesGroup<__TYPE>( m_##__TYPE, m_##__TYPE##InViews, m_##__TYPE##Views ) ) );
135
136#define INIT_XAOD(__TYPE, __STORE_TYPE) \
137 ATH_CHECK( initHandles( HandlesGroup<xAOD::__TYPE>( m_##__TYPE, m_##__TYPE##InViews, m_##__TYPE##Views ) ) ); \
138 ATH_CHECK( initAuxKey<xAOD::__STORE_TYPE>( m_##__TYPE.keys() ) );
139
141 INIT_XAOD( TrigCompositeContainer, TrigCompositeAuxContainer );
142
143 INIT_XAOD( TrigEMClusterContainer, TrigEMClusterAuxContainer );
144 INIT_XAOD( TrigCaloClusterContainer, TrigCaloClusterAuxContainer );
145 INIT_XAOD( TrigRingerRingsContainer, TrigRingerRingsAuxContainer );
146 INIT_XAOD( TrigElectronContainer, TrigElectronAuxContainer );
147 INIT_XAOD( ElectronContainer, ElectronAuxContainer );
148 INIT_XAOD( PhotonContainer, PhotonAuxContainer );
149 INIT_XAOD( TrigPhotonContainer, TrigPhotonAuxContainer );
150 INIT_XAOD( TrackParticleContainer, TrackParticleAuxContainer );
151 INIT_XAOD( TrigMissingETContainer, TrigMissingETAuxContainer );
152
153 INIT_XAOD( L2StandAloneMuonContainer, L2StandAloneMuonAuxContainer );
154 INIT_XAOD( L2CombinedMuonContainer, L2CombinedMuonAuxContainer );
155 INIT_XAOD( L2IsoMuonContainer, L2IsoMuonAuxContainer );
156 INIT_XAOD( MuonContainer, MuonAuxContainer );
157 INIT_XAOD( TauJetContainer, TauJetAuxContainer );
158 INIT_XAOD( DiTauJetContainer, DiTauJetAuxContainer );
159 INIT_XAOD( TauTrackContainer, TauTrackAuxContainer );
160 INIT_XAOD( JetContainer, JetAuxContainer );
161 INIT_XAOD( VertexContainer, VertexAuxContainer );
162 INIT_XAOD( TrigBphysContainer, TrigBphysAuxContainer );
163 INIT_XAOD( BTaggingContainer, BTaggingAuxContainer );
164 INIT_XAOD( BTagVertexContainer, BTagVertexAuxContainer );
165 INIT_XAOD( CaloClusterContainer, CaloClusterTrigAuxContainer ); // NOTE: Difference in interface and aux
166 INIT_XAOD( FlowElementContainer, FlowElementAuxContainer );
167 INIT_XAOD( TrigT2MbtsBitsContainer, TrigT2MbtsBitsAuxContainer );
168 INIT_XAOD( HIEventShapeContainer, HIEventShapeAuxContainer );
169 INIT_XAOD( TrigRNNOutputContainer, TrigRNNOutputAuxContainer );
170 INIT_XAOD( AFPSiHitsClusterContainer, AFPSiHitsClusterAuxContainer );
171 INIT_XAOD( AFPTrackContainer, AFPTrackAuxContainer );
172 INIT_XAOD( AFPToFTrackContainer, AFPToFTrackAuxContainer );
173 INIT_XAOD( AFPProtonContainer, AFPProtonAuxContainer );
174 INIT_XAOD( AFPVertexContainer, AFPVertexAuxContainer );
175
176 // Phase-I L1 RoIs EDM
177 INIT_XAOD( eFexEMRoIContainer, eFexEMRoIAuxContainer );
178 INIT_XAOD( eFexTauRoIContainer, eFexTauRoIAuxContainer );
179 INIT_XAOD( jFexTauRoIContainer, jFexTauRoIAuxContainer );
180 INIT_XAOD( jFexFwdElRoIContainer, jFexFwdElRoIAuxContainer );
181 INIT_XAOD( jFexSRJetRoIContainer, jFexSRJetRoIAuxContainer );
182 INIT_XAOD( jFexLRJetRoIContainer, jFexLRJetRoIAuxContainer );
183 INIT_XAOD( jFexMETRoIContainer, jFexMETRoIAuxContainer );
184 INIT_XAOD( jFexSumETRoIContainer, jFexSumETRoIAuxContainer );
185 INIT_XAOD( gFexJetRoIContainer, gFexJetRoIAuxContainer );
186 INIT_XAOD( gFexGlobalRoIContainer, gFexGlobalRoIAuxContainer);
187 INIT_XAOD( MuonRoIContainer, MuonRoIAuxContainer );
188
189#undef INIT
190#undef INIT_XAOD
191
192#define INIT_SHALLOW(__TYPE) \
193 ATH_CHECK( m_##__TYPE##ShallowCopy.initialize() ); \
194 renounceArray( m_##__TYPE##ShallowCopy ); \
195 for ( auto k: m_##__TYPE##ShallowCopy ) \
196 m_##__TYPE##ShallowCopyOut.push_back(k.key()); \
197 ATH_CHECK( m_##__TYPE##ShallowCopyOut.initialize() ); \
198 if(m_renounceOutputs) { renounceArray( m_##__TYPE##ShallowCopyOut ); }
199
202
203#undef INIT_SHALLOW
204
205 return StatusCode::SUCCESS;
206}
207
208template<class T>
210 std::unique_ptr<T> data;
211 bool doRecord{true};
212 void create( bool create, bool record ) {
214 if ( create )
215 data = std::make_unique<T>();
216 }
217
218 StatusCode record( SG::WriteHandle<T>& h ) {
219 if ( doRecord )
220 return h.record( std::move( data ) );
221 return StatusCode::SUCCESS;
222 }
223};
224
225template<class T, class STORE>
227 std::unique_ptr<T> data;
228 std::unique_ptr<STORE> store;
229 bool doRecord{true};
230
231 void create( bool create, bool record ) {
233 if ( create ) {
234 data = std::make_unique<T>();
235 store = std::make_unique<STORE>();
236 data->setStore( store.get() );
237 }
238 }
239
240 StatusCode record ( SG::WriteHandle<T>& h ) {
241 if ( doRecord )
242 return h.record( std::move( data ), std::move( store ) );
243 return StatusCode::SUCCESS;
244 }
245};
246
247template<typename T>
249 EventContext const&, T & ) const {
250 // if we are called it means views merging is requested but Type T does not support it (i.e. missing copy c'tor)
251 return StatusCode::FAILURE;
252
253}
254
255template<typename T>
256StatusCode HLTEDMCreator::viewsMerge( ViewContainer const& views, const SG::ReadHandleKey<T>& inViewKey,
257 EventContext const& context, T & output ) const {
258
259 using type_in_container = typename T::base_value_type;
260 StoreGateSvc* sg = evtStore().operator->(); // why the get() method is returing a null ptr is a puzzle, we have to use this ugly call to operator instead of it
261 ATH_CHECK( sg != nullptr );
262 ViewHelper::ViewMerger merger( sg, msg() );
263 ATH_CHECK( merger.mergeViewCollection<type_in_container>( views, inViewKey, context, output ) );
264
265 return StatusCode::SUCCESS;
266}
267
268
269StatusCode HLTEDMCreator::fixLinks( EventContext const& context ) const {
270 if ( m_fixLinks.value().empty() ) {
271 ATH_MSG_DEBUG("fixLinks: No collections defined for this tool");
272 return StatusCode::SUCCESS;
273 }
274
275 ATH_MSG_DEBUG("fixLinks called for " << m_fixLinks.size() << " of " << m_TrigCompositeContainer.size() << " collections");
276
277 // Do the remapping
278 int writeHandleArrayIndex = -1;
279
280 // Create a HandleKey that we can re-use during the loop (slightly better performance)
282 ATH_CHECK( readHandleKey.initialize() );
283
284 for ( const auto& writeHandleKey: m_TrigCompositeContainer ) {
285 // Check if we are re-mapping this handle
286 const bool doFixLinks = std::any_of(m_fixLinks.begin(), m_fixLinks.end(), [&](const std::string& s) { return s == writeHandleKey.key(); } );
287 if ( not doFixLinks ) {
288 ATH_MSG_DEBUG("Not requested to fix TrigComposite ElementLinks for " << writeHandleKey.key());
289 continue;
290 }
291
292 // Only increment this index for the sub-set of the TrigComposite collections that we are fixing. Mirror the initialize() logic.
293 ++writeHandleArrayIndex;
294
295 ATH_MSG_DEBUG("Fixing links: confirm collection is there: " << writeHandleKey.key() << ", write handle array index: " << writeHandleArrayIndex);
296 // Update key name
297 readHandleKey = writeHandleKey.key();
298 auto readHandle = SG::makeHandle(readHandleKey, context);
299 if ( not readHandle.isValid() ) { // object missing, this is now an error as we should have literally just created it
300 ATH_MSG_ERROR("Collection is not present. " << readHandleKey.key() << " should have been created by createIfMissing.");
301 return StatusCode::FAILURE;
302 }
303
304 ATH_MSG_DEBUG("Collection exists with size " << readHandle->size() << " Decision objects" );
305 ATH_MSG_DEBUG("Adding decorations: " << m_remapLinkColKeys.at( writeHandleArrayIndex ).key() << " and " << m_remapLinkColIndices.at( writeHandleArrayIndex ).key() );
306
308 keyDecor(m_remapLinkColKeys.at( writeHandleArrayIndex ), context );
310 indexDecor( m_remapLinkColIndices.at( writeHandleArrayIndex ), context );
311
312 // Examine each input TC
313 int decisionObjectIndex = -1;
314 for ( auto inputDecision : *( readHandle.cptr() ) ) {
315 ++decisionObjectIndex;
316
317 // Retrieve the link information for remapping
318 std::vector< SG::sgkey_t > remappedKeys = inputDecision->linkColKeys(); // Vec copy
319 std::vector< xAOD::TrigComposite::index_type > remappedIndexes = inputDecision->linkColIndices(); // Vec copy
320
321 // Search the linked collections for remapping
322 size_t const collectionTotal = inputDecision->linkColNames().size();
323 ATH_MSG_DEBUG(" Decision object #" << decisionObjectIndex << " has " << collectionTotal << " links");
324 for ( size_t elementLinkIndex = 0; elementLinkIndex < collectionTotal; ++elementLinkIndex ) {
325
326 // Load ElementLink identifiers (except for CLID)
327 std::string const collectionName = inputDecision->linkColNames().at(elementLinkIndex);
328 SG::sgkey_t const collectionKey = remappedKeys.at(elementLinkIndex); //Note: This is the existing before-remap key
329 std::string const keyString = *( evtStore()->keyToString( collectionKey ) );
330 xAOD::TrigComposite::index_type const collectionIndex = remappedIndexes.at(elementLinkIndex); //Note: This is the existing before-remap index
331
332 // Check for remapping in a merge
333 SG::sgkey_t newKey = 0;
334 size_t newIndex = 0;
335 bool isRemapped = evtStore()->tryELRemap( collectionKey, collectionIndex, newKey, newIndex);
336 if ( isRemapped ) {
337
338 ATH_MSG_DEBUG( " Remap link [" << collectionName <<"] from " << keyString << " to " << *( evtStore()->keyToString( newKey ) ) << ", from index " << collectionIndex << " to index " << newIndex );
339 remappedKeys[ elementLinkIndex ] = newKey;
340 remappedIndexes[ elementLinkIndex ] = newIndex;
341
342 } else {
343
344 ATH_MSG_DEBUG( " StoreGate did not remap link [" << collectionName << "] from " << keyString << " index " << collectionIndex );
345
346 }
347
348 }
349
350 // Save the remaps
351 keyDecor( *inputDecision ) = std::move(remappedKeys);
352 indexDecor( *inputDecision ) = std::move(remappedIndexes);
353
354 }
355 }
356
357 return StatusCode::SUCCESS;
358}
359
360
361template<typename T, typename STORE, typename G, typename M>
362StatusCode HLTEDMCreator::createIfMissing( const EventContext& context, const ConstHandlesGroup<T>& handles, G& generator, M merger ) const {
363
364 // Declare a ReadHandleKey that we can re-use during the loop for reading.
365 SG::ReadHandleKey<T> rhk("temp");
366
367 // Same for the Aux store. If there is none (void) this would not compile
368 // so we just define a dummy RHK, which will never be used, of type T again.
369 using AuxType = std::conditional_t<std::is_void_v<STORE>, T, STORE>;
370 SG::ReadHandleKey<AuxType> rhkAux("temp");
371
372 ATH_CHECK( rhk.initialize() && rhkAux.initialize() );
373
374 for (size_t i = 0; i < handles.out.size(); ++i) {
375 const SG::WriteHandleKey<T>& whk = handles.out.at(i);
376 rhk = whk.key(); // set the RHK to the same key as the WHK
377
378 if ( handles.views.empty() ) { // no merging will be needed
379 // Note: This is correct. We are testing if we can read, and if we cannot then we write.
380 // What we write will either be a dummy (empty) container, or be populated from N in-View collections.
381 auto readHandle = SG::makeHandle( rhk, context );
382 if ( readHandle.isValid() ) {
383 ATH_MSG_VERBOSE( rhk.key() << " is already present" );
384 generator.create(false, false);
385
386 // For xAOD types we need to ensure there is an Aux store. This can happen if the
387 // Aux store gets truncated for collections marked with "allowTruncation".
388 // The TriggerEDMDeserialiserAlg will already have created a DataLink to the Aux store
389 // for the interface container. Now we just need to create an empty Aux store.
390 if constexpr (!std::is_void_v<STORE>) {
391 rhkAux = rhk.key() + "Aux.";
392 auto readAuxHandle = SG::makeHandle(rhkAux, context);
393 if ( !readAuxHandle.isValid() ) {
394 // This is rare so we just create a WH as needed:
395 SG::WriteHandle<STORE> writeAuxHandle( rhkAux.key(), context );
396 ATH_MSG_DEBUG("Creating missing Aux store for " << rhk.key());
397 ATH_CHECK( writeAuxHandle.record(std::make_unique<STORE>()) );
398 }
399 }
400 } else {
401 ATH_MSG_DEBUG( rhk.key() << " is missing, creating it" );
402 generator.create(true, true);
403 }
404
405 } else {
406 // there are views, we assume that in the main store collection of given type#name is absent, else it will not work anyways
407 // simplest case, only one set of views is handled first
408 // below is handled the cases when the configuration of output keys is for example: A A B C C C D D E
409 // which means the first two collections come from first two views and because the names are the same they should end up in the same output collection
410 // thefore generators need to instructed to:
411 // - create new collection when a new name is handled (or for the first key)
412 // - and record when it is last identical name in the row (or it is last handled collection)
413 if ( handles.out.size() == 1 ) {
414 generator.create(true, true);
415 } else {
416 const bool doCreate = i == 0 or handles.out.at(i-1).key() != whk.key();
417 const bool doRecord = i == handles.out.size()-1 or handles.out.at(i+1).key() != whk.key();
418 ATH_MSG_DEBUG( "Instructing generator " << (doCreate ? "to" : "NOT TO") << " create collection and " << (doRecord ? "to" : "NOT TO") << " record collection in this iteration");
419 generator.create(doCreate, doRecord);
420 }
421
422 const SG::ReadHandleKey<ViewContainer>& viewsReadHandleKey = handles.views.at(i);
423 ATH_MSG_DEBUG("Will be trying to merge from the " << viewsReadHandleKey.key() << " view container into that output");
424
425 auto viewsHandle = SG::makeHandle( viewsReadHandleKey, context );
426 if ( viewsHandle.isValid() ) {
427 const SG::ReadHandleKey<T>& inViewReadHandleKey = handles.in.at(i);
428 ATH_MSG_DEBUG("Will be merging from " << viewsHandle->size() << " views using in-view key " << inViewReadHandleKey.key() );
429 ATH_CHECK( (this->*merger)( *viewsHandle, inViewReadHandleKey , context, *generator.data.get() ) );
430 } else {
431 ATH_MSG_DEBUG("Views " << viewsReadHandleKey.key() << " are missing. Will leave " << whk.key() << " output collection empty.");
432 }
433
434 // Also consider probe variants of each EventView.
435 // Not every container will have a corresponding set of (typically) lower-pT probe ROIs, but it's safer to always test.
436 const std::string viewsReadHandleKeyProbe = viewsReadHandleKey.key() + "_probe";
437 ATH_MSG_VERBOSE("Will try to merge from the " << viewsReadHandleKeyProbe << " view container into that output");
438
439 // Falling back to direct SG access here to avoid uninitiated key errors. This is safe to do in the context of the Trigger ControlFlow.
440 // I.e. if this collection is to exist in this event, then it is guaranteed to have been produced prior to this alg executing.
441 const ViewContainer* viewsContainer_probe = nullptr;
442 if (evtStore()->contains<ViewContainer>(viewsReadHandleKeyProbe)) {
443 ATH_CHECK(evtStore()->retrieve(viewsContainer_probe, viewsReadHandleKeyProbe));
444 }
445 if ( viewsContainer_probe ) {
446 const SG::ReadHandleKey<T>& inViewReadHandleKey = handles.in.at(i);
447 ATH_MSG_DEBUG("Will be merging from " << viewsContainer_probe->size() << " probe views using in-view key " << inViewReadHandleKey.key() );
448 ATH_CHECK( (this->*merger)( *viewsContainer_probe, inViewReadHandleKey , context, *generator.data.get() ) );
449 } else {
450 ATH_MSG_VERBOSE("Probe views " << viewsReadHandleKeyProbe << " are missing.");
451 }
452
453 }
454
455 auto writeHandle = SG::makeHandle( whk, context );
456 ATH_CHECK( generator.record( writeHandle ) );
457 }
458
459 return StatusCode::SUCCESS;
460}
461
462
463
464StatusCode HLTEDMCreator::createOutput(const EventContext& context) const {
465 ATH_MSG_DEBUG("Confirming / Creating this tool's output");
466 if ( m_dumpSGBefore )
467 ATH_MSG_DEBUG( evtStore()->dump() );
468
469#define CREATE(__TYPE) \
470 { \
471 plainGenerator<__TYPE> generator; \
472 ATH_CHECK( (createIfMissing<__TYPE, void>( context, ConstHandlesGroup<__TYPE>( m_##__TYPE, m_##__TYPE##InViews, m_##__TYPE##Views ), generator, &HLTEDMCreator::noMerge<__TYPE>)) ); \
473 }
474
476
477#undef CREATE
478
479#define CREATE_XAOD(__TYPE, __STORE_TYPE) \
480 { \
481 xAODGenerator<xAOD::__TYPE, xAOD::__STORE_TYPE> generator; \
482 ATH_CHECK( (createIfMissing<xAOD::__TYPE, xAOD::__STORE_TYPE>( context, ConstHandlesGroup<xAOD::__TYPE>( m_##__TYPE, m_##__TYPE##InViews, m_##__TYPE##Views ), generator, &HLTEDMCreator::viewsMerge<xAOD::__TYPE>)) ); \
483 }
484
485
486 CREATE_XAOD( TrigCompositeContainer, TrigCompositeAuxContainer );
487 CREATE_XAOD( TrigElectronContainer, TrigElectronAuxContainer );
488 CREATE_XAOD( ElectronContainer, ElectronAuxContainer );
489 CREATE_XAOD( PhotonContainer, PhotonAuxContainer );
490 CREATE_XAOD( TrigPhotonContainer, TrigPhotonAuxContainer );
491 CREATE_XAOD( TrigEMClusterContainer, TrigEMClusterAuxContainer );
492 CREATE_XAOD( TrigCaloClusterContainer, TrigCaloClusterAuxContainer );
493 CREATE_XAOD( TrigRingerRingsContainer, TrigRingerRingsAuxContainer );
494 CREATE_XAOD( TrackParticleContainer, TrackParticleAuxContainer );
495 CREATE_XAOD( TrigMissingETContainer, TrigMissingETAuxContainer );
496
497 CREATE_XAOD( L2StandAloneMuonContainer, L2StandAloneMuonAuxContainer );
498 CREATE_XAOD( L2CombinedMuonContainer, L2CombinedMuonAuxContainer );
499 CREATE_XAOD( L2IsoMuonContainer, L2IsoMuonAuxContainer );
500 CREATE_XAOD( MuonContainer, MuonAuxContainer );
501 CREATE_XAOD( TauJetContainer, TauJetAuxContainer );
502 CREATE_XAOD( DiTauJetContainer, DiTauJetAuxContainer );
503 CREATE_XAOD( TauTrackContainer, TauTrackAuxContainer );
504 CREATE_XAOD( CaloClusterContainer, CaloClusterTrigAuxContainer ); // NOTE: Difference in interface and aux
505 CREATE_XAOD( FlowElementContainer, FlowElementAuxContainer );
506 CREATE_XAOD( JetContainer, JetAuxContainer );
507 CREATE_XAOD( VertexContainer,VertexAuxContainer );
508 CREATE_XAOD( TrigBphysContainer, TrigBphysAuxContainer );
509 CREATE_XAOD( BTaggingContainer,BTaggingAuxContainer );
510 CREATE_XAOD( BTagVertexContainer,BTagVertexAuxContainer );
511 CREATE_XAOD( TrigT2MbtsBitsContainer, TrigT2MbtsBitsAuxContainer );
512 CREATE_XAOD( HIEventShapeContainer, HIEventShapeAuxContainer );
513 CREATE_XAOD( TrigRNNOutputContainer, TrigRNNOutputAuxContainer );
514 CREATE_XAOD( AFPSiHitsClusterContainer, AFPSiHitsClusterAuxContainer );
515 CREATE_XAOD( AFPTrackContainer, AFPTrackAuxContainer );
516 CREATE_XAOD( AFPToFTrackContainer, AFPToFTrackAuxContainer );
517 CREATE_XAOD( AFPProtonContainer, AFPProtonAuxContainer );
518 CREATE_XAOD( AFPVertexContainer, AFPVertexAuxContainer );
519
520 // Phase-I L1 RoIs EDM
521 CREATE_XAOD( eFexEMRoIContainer, eFexEMRoIAuxContainer );
522 CREATE_XAOD( eFexTauRoIContainer, eFexTauRoIAuxContainer );
523 CREATE_XAOD( jFexTauRoIContainer, jFexTauRoIAuxContainer );
524 CREATE_XAOD( jFexFwdElRoIContainer, jFexFwdElRoIAuxContainer );
525 CREATE_XAOD( jFexSRJetRoIContainer, jFexSRJetRoIAuxContainer );
526 CREATE_XAOD( jFexLRJetRoIContainer, jFexLRJetRoIAuxContainer );
527 CREATE_XAOD( jFexMETRoIContainer, jFexMETRoIAuxContainer );
528 CREATE_XAOD( jFexSumETRoIContainer, jFexSumETRoIAuxContainer );
529 CREATE_XAOD( gFexJetRoIContainer, gFexJetRoIAuxContainer );
530 CREATE_XAOD( gFexGlobalRoIContainer, gFexGlobalRoIAuxContainer);
531 CREATE_XAOD( MuonRoIContainer, MuonRoIAuxContainer );
532
533 // After view collections are merged, need to update collection links
534 ATH_CHECK( fixLinks(context) );
535
536#undef CREATE_XAOD
537
538 // special cases
539 #define CREATE_SHALLOW(__TYPE) \
540 { \
541 for ( size_t index = 0; index < m_##__TYPE##ShallowCopy.size(); ++index ){ \
542 auto readHandle = SG::makeHandle<xAOD::__TYPE> ( m_##__TYPE##ShallowCopy[index], context ); \
543 if ( not readHandle.isValid() ) { \
544 ATH_MSG_DEBUG( "Creating missing "#__TYPE"ShallowCopy " << m_##__TYPE##ShallowCopy[index].key() ); \
545 auto writeHandle = SG::makeHandle( m_##__TYPE##ShallowCopyOut[index], context ); \
546 ATH_CHECK( writeHandle.record( std::make_unique<xAOD::__TYPE>(), std::make_unique<xAOD::ShallowAuxContainer>() )); \
547 } else { \
548 ATH_MSG_DEBUG( #__TYPE"ShallowCopy " << m_##__TYPE##ShallowCopyOut[index].key() << " present in the event, done nothing"); \
549 } \
550 } \
551 }
552
555
556 #undef CREATE_SHALLOW
557
558 if ( m_dumpSGAfter )
559 ATH_MSG_DEBUG( evtStore()->dump() );
560
561 ATH_MSG_DEBUG("Done");
562 return StatusCode::SUCCESS;
563}
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_VERBOSE(x,...)
#define CREATE_SHALLOW(__TYPE)
#define INIT(__TYPE)
#define INIT_XAOD(__TYPE, __STORE_TYPE)
#define INIT_SHALLOW(__TYPE)
#define CREATE(__TYPE)
#define CREATE_XAOD(__TYPE, __STORE_TYPE)
JetContainer_v1 JetContainer
Definition of the current "jet container version".
#define G(x, y, z)
Definition MD5.cxx:113
Handle class for adding a decoration to an object.
const std::string * keyToString(sgkey_t key) const
Find the string corresponding to a given key.
MuonContainer_v1 MuonContainer
Definition of the current "Muon container version".
DataVector< SG::View > ViewContainer
View container for recording in StoreGate.
Definition View.h:290
Header file for AthHistogramAlgorithm.
size_type size() const noexcept
Returns the number of elements in the collection.
StatusCode createIfMissing(const EventContext &context, const ConstHandlesGroup< T > &handles, G &generator, M merger) const
Gaudi::Property< bool > m_dumpSGAfter
Gaudi::Property< bool > m_renounceOutputs
StatusCode initAuxKey(const std::vector< SG::VarHandleKey * > &keys)
Register AuxStore keys for the given keys.
virtual StatusCode initialize() override
StatusCode viewsMerge(ViewContainer const &views, const SG::ReadHandleKey< T > &inViewKey, EventContext const &context, T &output) const
StatusCode initHandles(const HandlesGroup< T > &handles)
Init related handles.
SG::WriteDecorHandleKeyArray< xAOD::TrigCompositeContainer, std::vector< SG::sgkey_t > > m_remapLinkColKeys
SG::WriteDecorHandleKeyArray< xAOD::TrigCompositeContainer, std::vector< xAOD::TrigComposite::index_type > > m_remapLinkColIndices
Gaudi::Property< bool > m_dumpSGBefore
Gaudi::Property< std::vector< std::string > > m_fixLinks
virtual StatusCode createOutput(const EventContext &context) const override
StatusCode fixLinks(EventContext const &context) const
StatusCode noMerge(ViewContainer const &views, const SG::ReadHandleKey< T > &inViewKey, EventContext const &context, T &output) const
Property holding a SG store/key/clid from which a ReadHandle is made.
A property holding a SG store/key/clid from which a VarHandle is made.
const std::string & key() const
Return the StoreGate ID for the referenced object.
StatusCode initialize(bool used=true)
If this object is used as a property, then this should be called during the initialize phase.
Handle class for adding a decoration to an object.
Property holding a SG store/key/clid from which a WriteHandle is made.
StatusCode record(std::unique_ptr< T > data)
Record a const object to the store.
The Athena Transient Store API.
StatusCode mergeViewCollection(ViewContainer const &viewVector, SG::ReadHandleKey< T > const &queryKey, EventContext const &sourceContext, T &outputData)
Definition ViewHelper.h:144
bool contains(const std::string &s, const std::string &regx)
does a string contain the substring
Definition hcg.cxx:116
uint32_t sgkey_t
Type used for hashed StoreGate key+CLID pairs.
Definition sgkey_t.h:32
SG::ReadCondHandle< T > makeHandle(const SG::ReadCondHandleKey< T > &key, const EventContext &ctx=Gaudi::Hive::currentContext())
-event-from-file
const SG::WriteHandleKeyArray< T > & out
const SG::ReadHandleKeyArray< T > & in
const SG::ReadHandleKeyArray< ViewContainer > & views
SG::ReadHandleKeyArray< ViewContainer > & views
SG::WriteHandleKeyArray< T > & out
SG::ReadHandleKeyArray< T > & in
std::unique_ptr< T > data
StatusCode record(SG::WriteHandle< T > &h)
void create(bool create, bool record)
void create(bool create, bool record)
std::unique_ptr< STORE > store
StatusCode record(SG::WriteHandle< T > &h)
std::unique_ptr< T > data
MsgStream & msg
Definition testRead.cxx:32