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