16 #include <TDirectory.h>
46 class TEventNotifier :
public ::TObject {
51 : m_tree( 0 ), m_event( 0 ) {}
64 virtual ::Bool_t Notify() {
65 if( ( ! m_tree ) || ( ! m_event ) ) {
66 ::Error(
"TEventNotifier::Notify",
71 if( ! m_event->readFrom( m_tree ) ) {
72 ::Error(
"TEventNotifier::Notify",
102 class TTransObjectHolder {
106 class TVirtualTransObject {
109 virtual ~TVirtualTransObject() {}
113 template<
typename T >
114 class TTransObject :
public TVirtualTransObject {
117 TTransObject( std::unique_ptr< T >&&
obj )
118 : m_obj( std::move(
obj ) ) {}
123 if( ! ROOT::Internal::gROOTLocal ) {
124 (void)m_obj.release();
127 if (TTransObjectHolder::s_inCleanup)
128 (void)m_obj.release();
131 std::unique_ptr< T > m_obj;
136 TTransObjectHolder() : m_objects() {}
139 template<
typename T >
140 void add( std::unique_ptr< T >&&
obj ) {
141 m_objects.push_back( std::unique_ptr< TVirtualTransObject >(
142 new TTransObject< T >( std::move(
obj ) ) ) );
156 ~Canary() { TTransObjectHolder::s_inCleanup =
true; }
160 std::vector< std::unique_ptr< TVirtualTransObject > > m_objects;
163 inline static std::atomic<bool> s_inCleanup{
false};
172 static ::TTransObjectHolder s_objectHolder;
174 static ::TTransObjectHolder::Canary s_canary;
190 ::Error(
"xAOD::MakeTransientTrees",
191 XAOD_MESSAGE(
"Couldn't set up the reading of the input "
197 ::TTree* metaTree =
dynamic_cast< ::TTree*
>(
ifile->Get(
"MetaData" ) );
199 ::Error(
"xAOD::MakeTransientTrees",
200 XAOD_MESSAGE(
"Couldn't access metadata tree \"MetaData\" "
201 "in the input file" ) );
207 ::TTree* meta = MakeTransientMetaTree( *
event, metaTree );
211 s_objectHolder.add( std::move(
event ) );
219 s_objectHolder.clear();
228 ::Error(
"xAOD::MakeTransientTree",
239 auto eventTree = std::make_unique< xAODTEventTree >(
event,
treeName );
245 if(
event.getEntry( 0 ) < 0 ) {
246 ::Error(
"xAOD::MakeTransientTree",
254 for( ; ef_itr != ef_end; ++ef_itr ) {
275 ::TClass*
cl = ::TClass::GetClass( efe.
className().c_str() );
279 if(
cl->InheritsFrom(
"SG::IConstAuxStore" ) ) {
284 const std::type_info* ti =
cl->GetTypeInfo();
286 ::Warning(
"xAOD::MakeTransientTree",
287 "Couldn't find std::type_info object for type %s "
293 static constexpr
bool METADATA =
false;
300 std::make_unique< xAODTEventBranch >( *eventTree,
event, *ti,
303 eventTree->AddBranch( std::move(
br ) );
308 ::TTree*
result = eventTree.get();
310 s_objectHolder.add( std::move( eventTree ) );
313 ::Info(
"xAOD::MakeTransientTree",
314 "Created transient tree \"%s\" in ROOT's common memory",
324 std::unique_ptr< TEvent >
event(
new TEvent(
mode ) );
326 ::Error(
"xAOD::MakeTransientTree",
327 XAOD_MESSAGE(
"Couldn't set up the reading of the input "
336 s_objectHolder.add( std::move(
event ) );
346 std::unique_ptr< ::TEventNotifier > notifier( new ::TEventNotifier() );
350 if( !
event->readFrom( itree ) ) {
351 ::Error(
"xAOD::MakeTransientTree",
352 XAOD_MESSAGE(
"Couldn't set up the reading of the input "
358 if(
event->getEntry( 0 ) < 0 ) {
359 ::Error(
"xAOD::MakeTransientTree",
360 XAOD_MESSAGE(
"Couldn't load event 0 from the chain" ) );
366 notifier->Setup( itree,
event.get() );
367 itree->SetNotify( notifier.get() );
370 ::TTree*
result = MakeTransientTree( *
event, itree->GetName() );
373 s_objectHolder.add( std::move(
event ) );
374 s_objectHolder.add( std::move( notifier ) );
387 auto metaTree = std::make_unique< xAODTMetaTree >(
event );
393 TObjArray*
branches = persMetaTree->GetListOfBranches();
394 for( ::Int_t
i = 0;
i <
branches->GetEntries(); ++
i ) {
397 ::TBranch*
br =
dynamic_cast< ::TBranch*
>(
branches->At(
i ) );
399 ::Error(
"xAOD::MakeTransientMetaTree",
400 XAOD_MESSAGE(
"Couldn't access branch %i as a TBranch" ),
407 if( ! strcmp(
br->GetName(),
"EventFormat" ) )
continue;
410 ::TClass*
cl = ::TClass::GetClass(
br->GetClassName(), kTRUE, kTRUE );
414 const std::type_info* ti =
cl->GetTypeInfo();
418 if(
cl->InheritsFrom(
"SG::IConstAuxStore" ) ) {
423 auto mbr = std::make_unique< xAODTMetaBranch >( *metaTree,
event, *ti,
425 br->GetClassName() );
426 metaTree->AddBranch( std::move( mbr ) );
430 ::TTree*
result = metaTree.get();
432 s_objectHolder.add( std::move( metaTree ) );
435 ::Info(
"xAOD::MakeTransientMetaTree",
436 "Created transient metadata tree \"MetaData\" in ROOT's common "
442 const char* eventTreeName,
447 std::unique_ptr< TEvent >
event(
new TEvent(
mode ) );
448 if( !
event->readFrom(
ifile, kTRUE, eventTreeName ) ) {
449 ::Error(
"xAOD::MakeTransientMetaTree",
450 XAOD_MESSAGE(
"Couldn't set up the reading of the input "
456 ::TTree* metaTree =
dynamic_cast< ::TTree*
>(
ifile->Get(
"MetaData" ) );
458 ::Error(
"xAOD::MakeTransientMetaTree",
459 XAOD_MESSAGE(
"Couldn't access metadata tree \"MetaData\" "
460 "in the input file" ) );
465 ::TTree*
result = MakeTransientMetaTree( *
event, metaTree );
468 s_objectHolder.add( std::move(
event ) );
475 const char* eventTreeName,
479 std::unique_ptr< ::TChain > helperChain( new ::TChain( eventTreeName ) );
480 ::TObjArray*
files = ichain->GetListOfFiles();
481 for( ::Int_t
i = 0;
i <
files->GetEntries(); ++
i ) {
482 helperChain->Add(
files->At(
i )->GetTitle() );
488 if( !
event->readFrom( helperChain.get(), kTRUE ) ) {
489 ::Error(
"xAOD::MakeTransientMetaTree",
490 XAOD_MESSAGE(
"Couldn't set up the reading of the input "
496 ::TTree*
result = MakeTransientMetaTree( *
event, ichain );
499 s_objectHolder.add( std::move( helperChain ) );
500 s_objectHolder.add( std::move(
event ) );