| The Gaudi Framework v29r1 (5cd95fa2)

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

RootDataConnection.cpp
Go to the documentation of this file.
1 //====================================================================
2 // RootDataConnection.cpp
3 //--------------------------------------------------------------------
4 //
5 // Author : M.Frank
6 //====================================================================
7
8 // Framework include files
9 #include "RootCnv/RootDataConnection.h"
10 #include "GaudiKernel/DataObject.h"
11 #include "GaudiKernel/IIncidentSvc.h"
12 #include "GaudiKernel/IOpaqueAddress.h"
13 #include "GaudiKernel/IRegistry.h"
14 #include "GaudiKernel/Incident.h"
15 #include "GaudiKernel/LinkManager.h"
16 #include "GaudiKernel/MsgStream.h"
17 #include "GaudiKernel/strcasecmp.h"
18 #include "RootUtils.h"
19 // ROOT include files
20 #include "TBranch.h"
21 #include "TClass.h"
22 #include "TFile.h"
23 #include "TLeaf.h"
24 #include "TROOT.h"
25 #include "TTree.h"
26 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
27 #include "Compression.h"
28 static int s_compressionLevel = ROOT::CompressionSettings( ROOT::kLZMA, 4 );
29 #else
30 static int s_compressionLevel = 1;
31 #endif
32
33 // C/C++ include files
34 #include <numeric>
35 #include <stdexcept>
36
37 using namespace Gaudi;
38 using namespace std;
39 typedef const string& CSTR;
40
41 static const string s_empty;
42 static const string s_local = "<localDB>";
43
44 #ifdef __POOL_COMPATIBILITY
45 #include "PoolTool.h"
46 #endif
47 #include "RootTool.h"
48
49 namespace
50 {
51 std::array<char, 256> init_table()
52 {
53 std::array<char, 256> table;
54 std::iota( std::begin( table ), std::end( table ), 0 );
55 return table;
56 }
57 }
58
59 static bool match_wild( const char* str, const char* pat )
60 {
61 //
62 // Credits: Code from Alessandro Felice Cantatore.
63 //
64 static const std::array<char, 256> table = init_table();
65 const char *s, *p;
66 bool star = false;
67 loopStart:
68 for ( s = str, p = pat; *s; ++s, ++p ) {
69 switch ( *p ) {
70 case '?':
71 if ( *s == '.' ) goto starCheck;
72 break;
73 case '*':
74 star = true;
75 str = s, pat = p;
76 do {
77 ++pat;
78 } while ( *pat == '*' );
79 if ( !*pat ) return true;
80 goto loopStart;
81 default:
82 if ( table[*s] != table[*p] ) goto starCheck;
83 break;
84 } /* endswitch */
85 } /* endfor */
86 while ( *p == '*' ) ++p;
87 return ( !*p );
88
89 starCheck:
90 if ( !star ) return false;
91 str++;
92 goto loopStart;
93 }
94
96 long RootConnectionSetup::setCompression( const std::string& compression )
97 {
98 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
99 int res = 0, level = ROOT::CompressionSettings( ROOT::kLZMA, 6 );
100 auto idx = compression.find( ':' );
101 if ( idx != string::npos ) {
102 string alg = compression.substr( 0, idx );
103 ROOT::ECompressionAlgorithm alg_code = ROOT::kUseGlobalSetting;
104 if ( strcasecmp( alg.c_str(), "ZLIB" ) == 0 )
105 alg_code = ROOT::kZLIB;
106 else if ( strcasecmp( alg.c_str(), "LZMA" ) == 0 )
107 alg_code = ROOT::kLZMA;
108 else
109 throw runtime_error( "ERROR: request to set unknown ROOT compression algorithm:" + alg );
110 res = ::sscanf( compression.c_str() + idx + 1, "%d", &level );
111 if ( res == 1 ) {
112 s_compressionLevel = ROOT::CompressionSettings( alg_code, level );
113 return StatusCode::SUCCESS;
114 }
115 throw runtime_error( "ERROR: request to set unknown ROOT compression level:" + compression.substr( idx + 1 ) );
116 } else if ( 1 == ::sscanf( compression.c_str(), "%d", &level ) ) {
117 s_compressionLevel = level;
118 return StatusCode::SUCCESS;
119 }
120 throw runtime_error( "ERROR: request to set unknown ROOT compression mechanism:" + compression );
121 #else
122 if ( !compression.empty() ) {
123 }
124 return StatusCode::SUCCESS;
125 #endif
126 }
127
129 int RootConnectionSetup::compression() { return s_compressionLevel; }
130
132 void RootConnectionSetup::setMessageSvc( MsgStream* m ) { m_msgSvc.reset( m ); }
133
135 void RootConnectionSetup::setIncidentSvc( IIncidentSvc* s ) { m_incidentSvc.reset( s ); }
136
138 RootDataConnection::RootDataConnection( const IInterface* owner, CSTR fname,
139 std::shared_ptr<RootConnectionSetup> setup )
140 : IDataConnection( owner, fname ), m_setup( std::move( setup ) )
141 { // 01234567890123456789012345678901234567890
142 // Check if FID: A82A3BD8-7ECB-DC11-8DC0-000423D950B0
143 if ( fname.length() == 36 && fname[8] == '-' && fname[13] == '-' && fname[18] == '-' && fname[23] == '-' ) {
144 m_name = "FID:" + fname;
145 }
146 m_age = 0;
147 m_file.reset();
148 addClient( owner );
149 }
150
152 void RootDataConnection::addClient( const IInterface* client ) { m_clients.insert( client ); }
153
155 size_t RootDataConnection::removeClient( const IInterface* client )
156 {
157 auto i = m_clients.find( client );
158 if ( i != m_clients.end() ) m_clients.erase( i );
159 return m_clients.size();
160 }
161
163 bool RootDataConnection::lookupClient( const IInterface* client ) const
164 {
165 auto i = m_clients.find( client );
166 return i != m_clients.end();
167 }
168
170 void RootDataConnection::badWriteError( const string& msg ) const
171 {
172 msgSvc() << MSG::ERROR << "File:" << fid() << "Failed action:" << msg << endmsg;
173 }
174
176 void RootDataConnection::saveStatistics( CSTR statisticsFile )
177 {
178 if ( m_statistics ) {
179 m_statistics->Print();
180 if ( !statisticsFile.empty() ) m_statistics->SaveAs( statisticsFile.c_str() );
181 m_statistics.reset();
182 }
183 }
184
186 void RootDataConnection::enableStatistics( CSTR section )
187 {
188 if ( m_statistics ) {
189 TTree* t = getSection( section, false );
190 if ( t ) {
191 m_statistics.reset( new TTreePerfStats( ( section + "_ioperf" ).c_str(), t ) );
192 return;
193 }
194 msgSvc() << MSG::WARNING << "Failed to enable perfstats for tree:" << section << endmsg;
195 return;
196 }
197 msgSvc() << MSG::INFO << "Perfstats are ALREADY ENABLED." << endmsg;
198 }
199
201 RootDataConnection::Tool* RootDataConnection::makeTool()
202 {
203 if ( !m_refs ) m_refs = (TTree*)m_file->Get( "Refs" );
204 if ( m_refs ) m_tool.reset( new RootTool( this ) );
205 #ifdef __POOL_COMPATIBILITY
206 else if ( m_file->Get( "##Links" ) != nullptr )
207 m_tool.reset( new PoolTool( this ) );
208 #endif
209 else
210 m_tool.reset();
211 return m_tool.get();
212 }
213
215 StatusCode RootDataConnection::connectRead()
216 {
217 m_file.reset( TFile::Open( m_pfn.c_str() ) );
218 if ( !m_file || m_file->IsZombie() ) {
219 m_file.reset();
220 return StatusCode::FAILURE;
221 }
222 StatusCode sc = StatusCode::FAILURE;
223 msgSvc() << MSG::DEBUG << "Opened file " << m_pfn << " in mode READ. [" << m_fid << "]" << endmsg << MSG::DEBUG;
224 if ( msgSvc().isActive() ) m_file->ls();
225 msgSvc() << MSG::VERBOSE;
226 if ( msgSvc().isActive() ) m_file->Print();
227 if ( makeTool() ) {
228 sc = m_tool->readRefs();
229 sc.ignore();
230 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
231 if ( sc.getCode() == ROOT_READ_ERROR ) {
232 IIncidentSvc* inc = m_setup->incidentSvc();
233 if ( inc ) {
234 inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) );
235 }
236 }
237 #endif
238 }
239 if ( !sc.isSuccess() ) return sc;
240 bool need_fid = m_fid == m_pfn;
241 string fid = m_fid;
242 m_mergeFIDs.clear();
243 for ( auto& elem : m_params ) {
244 if ( elem.first == "FID" ) {
245 m_mergeFIDs.push_back( elem.second );
246 if ( elem.second != m_fid ) {
247 msgSvc() << MSG::DEBUG << "Check FID param:" << elem.second << endmsg;
248 // if ( m_fid == m_pfn ) {
249 m_fid = elem.second;
250 //}
251 }
252 }
253 }
254 if ( !need_fid && fid != m_fid ) {
255 msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
256 << "for PFN:" << m_pfn << endmsg;
257 return StatusCode::FAILURE;
258 }
259 msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg << "for PFN:" << m_pfn
260 << endmsg;
261 return sc;
262 }
263
265 StatusCode RootDataConnection::connectWrite( IoType typ )
266 {
267 int compress = RootConnectionSetup::compression();
268 msgSvc() << MSG::DEBUG;
269 switch ( typ ) {
270 case CREATE:
271 resetAge();
272 m_file.reset( TFile::Open( m_pfn.c_str(), "CREATE", "Root event data", compress ) );
273 m_refs = new TTree( "Refs", "Root reference data" );
274 msgSvc() << "Opened file " << m_pfn << " in mode CREATE. [" << m_fid << "]" << endmsg;
275 m_params.emplace_back( "PFN", m_pfn );
276 if ( m_fid != m_pfn ) {
277 m_params.emplace_back( "FID", m_fid );
278 }
279 makeTool();
280 break;
281 case RECREATE:
282 resetAge();
283 m_file.reset( TFile::Open( m_pfn.c_str(), "RECREATE", "Root event data", compress ) );
284 msgSvc() << "Opened file " << m_pfn << " in mode RECREATE. [" << m_fid << "]" << endmsg;
285 m_refs = new TTree( "Refs", "Root reference data" );
286 m_params.emplace_back( "PFN", m_pfn );
287 if ( m_fid != m_pfn ) {
288 m_params.emplace_back( "FID", m_fid );
289 }
290 makeTool();
291 break;
292 case UPDATE:
293 resetAge();
294 m_file.reset( TFile::Open( m_pfn.c_str(), "UPDATE", "Root event data", compress ) );
295 msgSvc() << "Opened file " << m_pfn << " in mode UPDATE. [" << m_fid << "]" << endmsg;
296 if ( m_file && !m_file->IsZombie() ) {
297 if ( makeTool() ) {
298 StatusCode sc = m_tool->readRefs();
299 sc.ignore();
300 if ( sc.getCode() == ROOT_READ_ERROR ) {
301 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
302 IIncidentSvc* inc = m_setup->incidentSvc();
303 if ( inc ) {
304 inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) );
305 }
306 #endif
307 }
308 return sc;
309 }
310 TDirectory::TContext ctxt( m_file.get() );
311 m_refs = new TTree( "Refs", "Root reference data" );
312 makeTool();
313 return StatusCode::SUCCESS;
314 }
315 break;
316 default:
317 m_refs = nullptr;
318 m_file.reset();
319 return StatusCode::FAILURE;
320 }
321 return m_file ? StatusCode::SUCCESS : StatusCode::FAILURE;
322 }
323
325 StatusCode RootDataConnection::disconnect()
326 {
327 if ( m_file ) {
328 if ( !m_file->IsZombie() ) {
329 if ( m_file->IsWritable() ) {
330 msgSvc() << MSG::DEBUG;
331 TDirectory::TContext ctxt( m_file.get() );
332 if ( m_refs ) {
333 if ( !m_tool->saveRefs().isSuccess() ) badWriteError( "Saving References" );
334 if ( m_refs->Write() < 0 ) badWriteError( "Write Reference branch" );
335 }
336 for ( auto& i : m_sections ) {
337 if ( i.second ) {
338 if ( i.second->Write() < 0 ) badWriteError( "Write section:" + i.first );
339 msgSvc() << "Disconnect section " << i.first << " " << i.second->GetName() << endmsg;
340 }
341 }
342 m_sections.clear();
343 }
344 msgSvc() << MSG::DEBUG;
345 if ( msgSvc().isActive() ) m_file->ls();
346 msgSvc() << MSG::VERBOSE;
347 if ( msgSvc().isActive() ) m_file->Print();
348 m_file->Close();
349 }
350 msgSvc() << MSG::DEBUG << "Disconnected file " << m_pfn << " " << m_file->GetName() << endmsg;
351 m_file.reset();
352 m_tool.reset();
353 }
354 return StatusCode::SUCCESS;
355 }
356
358 TTree* RootDataConnection::getSection( CSTR section, bool create )
359 {
360 TTree* t = m_sections[section];
361 if ( !t ) {
362 t = (TTree*)m_file->Get( section.c_str() );
363 if ( !t && create ) {
364 TDirectory::TContext ctxt( m_file.get() );
365 t = new TTree( section.c_str(), "Root data for Gaudi" );
366 }
367 if ( t ) {
368 int cacheSize = m_setup->cacheSize;
369 if ( create ) {
370 // t->SetAutoFlush(100);
371 }
372 if ( section == m_setup->loadSection && cacheSize > -2 ) {
373 MsgStream& msg = msgSvc();
374 int learnEntries = m_setup->learnEntries;
375 t->SetCacheSize( cacheSize );
376 t->SetCacheLearnEntries( learnEntries );
377 msg << MSG::DEBUG;
378 if ( create ) {
379 msg << "Tree:" << section << "Setting up tree cache:" << cacheSize << endmsg;
380 } else {
381 const StringVec& vB = m_setup->vetoBranches;
382 const StringVec& cB = m_setup->cacheBranches;
383 msg << "Tree:" << section << " Setting up tree cache:" << cacheSize << " Add all branches." << endmsg;
384 msg << "Tree:" << section << " Learn for " << learnEntries << " entries." << endmsg;
385
386 if ( cB.empty() && vB.empty() ) {
387 msg << "Adding (default) all branches to tree cache." << endmsg;
388 t->AddBranchToCache( "*", kTRUE );
389 }
390 if ( cB.size() == 1 && cB[0] == "*" ) {
391 msg << "Adding all branches to tree cache according to option \"CacheBranches\"." << endmsg;
392 t->AddBranchToCache( "*", kTRUE );
393 } else {
394 for ( TIter it( t->GetListOfBranches() ); it.Next(); ) {
395 const char* n = ( (TNamed*)( *it ) )->GetName();
396 bool add = false, veto = false;
397 for ( const auto& i : cB ) {
398 if ( !match_wild( n, ( i ).c_str() ) ) continue;
399 add = true;
400 break;
401 }
402 for ( auto i = vB.cbegin(); !add && i != vB.cend(); ++i ) {
403 if ( !match_wild( n, ( *i ).c_str() ) ) continue;
404 veto = true;
405 break;
406 }
407 if ( add && !veto ) {
408 msg << "Add " << n << " to branch cache." << endmsg;
409 t->AddBranchToCache( n, kTRUE );
410 } else {
411 msg << "Do not cache branch " << n << endmsg;
412 }
413 }
414 }
415 }
416 }
417 m_sections[section] = t;
418 }
419 }
420 return t;
421 }
422
424 TBranch* RootDataConnection::getBranch( CSTR section, CSTR branch_name, TClass* cl, void* ptr, int buff_siz,
425 int split_lvl )
426 {
427 string n = branch_name;
428 std::replace_if( std::begin( n ), std::end( n ), []( const char c ) { return !isalnum( c ); }, '_' );
429 n += ".";
430 TTree* t = getSection( section, true );
431 TBranch* b = t->GetBranch( n.c_str() );
432 if ( !b && cl && m_file->IsWritable() ) {
433 b = t->Branch( n.c_str(), cl->GetName(), (void*)( ptr ? &ptr : nullptr ), buff_siz, split_lvl );
434 }
435 if ( !b ) b = t->GetBranch( branch_name.c_str() );
436 if ( b ) b->SetAutoDelete( kFALSE );
437 return b;
438 }
439
441 int RootDataConnection::makeLink( CSTR p )
442 {
443 auto ip = std::find( std::begin( m_links ), std::end( m_links ), p );
444 if ( ip != std::end( m_links ) ) return std::distance( std::begin( m_links ), ip );
445 m_links.push_back( p );
446 return m_links.size() - 1;
447 }
448
450 CSTR RootDataConnection::getDb( int which ) const
451 {
452 if ( ( which >= 0 ) && ( size_t( which ) < m_dbs.size() ) ) {
453 if ( *( m_dbs.begin() + which ) == s_local ) return m_fid;
454 return *( m_dbs.begin() + which );
455 }
456 return s_empty;
457 }
458
460 CSTR RootDataConnection::empty() const { return s_empty; }
461
463 pair<int, unsigned long> RootDataConnection::saveObj( CSTR section, CSTR cnt, TClass* cl, DataObject* pObj,
464 int buff_siz, int split_lvl, bool fill )
465 {
466 DataObjectPush push( pObj );
467 return save( section, cnt, cl, pObj, buff_siz, split_lvl, fill );
468 }
469
471 pair<int, unsigned long> RootDataConnection::save( CSTR section, CSTR cnt, TClass* cl, void* pObj, int buff_siz,
472 int split_lvl, bool fill_missing )
473 {
474 split_lvl = 0;
475 TBranch* b = getBranch( section, cnt, cl, pObj ? &pObj : nullptr, buff_siz, split_lvl );
476 if ( b ) {
477 Long64_t evt = b->GetEntries();
478 // msgSvc() << MSG::DEBUG << cnt.c_str() << " Obj:" << (void*)pObj
479 // << " Split:" << split_lvl << " Buffer size:" << buff_siz << endl;
480 if ( fill_missing ) {
481 Long64_t num, nevt = b->GetTree()->GetEntries();
482 if ( nevt > evt ) {
483 b->SetAddress( nullptr );
484 num = nevt - evt;
485 while ( num > 0 ) {
486 b->Fill();
487 --num;
488 }
489 msgSvc() << MSG::DEBUG << "Added " << long( nevt - evt ) << " / Tree: " << nevt
490 << " / Branch: " << b->GetEntries() + 1 << " NULL entries to:" << cnt << endmsg;
491 evt = b->GetEntries();
492 }
493 }
494 b->SetAddress( &pObj );
495 return {b->Fill(), evt};
496 }
497 if ( pObj ) {
498 msgSvc() << MSG::ERROR << "Failed to access branch " << m_name << "/" << cnt << endmsg;
499 }
500 return {-1, ~0};
501 }
502
504 int RootDataConnection::loadObj( CSTR section, CSTR cnt, unsigned long entry, DataObject*& pObj )
505 {
506 TBranch* b = getBranch( section, cnt );
507 if ( b ) {
508 TClass* cl = gROOT->GetClass( b->GetClassName(), kTRUE );
509 if ( cl ) {
510 int nb = -1;
511 pObj = (DataObject*)cl->New();
512 {
513 DataObjectPush push( pObj );
514 b->SetAddress( &pObj );
515 if ( section == m_setup->loadSection ) {
516 TTree* t = b->GetTree();
517 if ( Long64_t( entry ) != t->GetReadEntry() ) {
518 t->LoadTree( Long64_t( entry ) );
519 }
520 }
521 nb = b->GetEntry( entry );
522 msgSvc() << MSG::VERBOSE;
523 if ( msgSvc().isActive() ) {
524 msgSvc() << "Load [" << entry << "] --> " << section << ":" << cnt << " " << nb << " bytes." << endmsg;
525 }
526 if ( nb < 0 ) { // This is definitely an error...ROOT says if reads fail, -1 is issued.
527 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
528 IIncidentSvc* inc = m_setup->incidentSvc();
529 if ( inc ) {
530 inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) );
531 }
532 #endif
533 } else if ( nb == 0 && pObj->clID() == CLID_DataObject ) {
534 TFile* f = b->GetFile();
535 int vsn = f->GetVersion();
536 if ( vsn < 52400 ) {
537 // For Gaudi v21r5 (ROOT 5.24.00b) DataObject::m_version was not written!
538 // Still this call be well be successful.
539 nb = 1;
540 } else if ( vsn > 1000000 && ( vsn % 1000000 ) < 52400 ) {
541 // dto. Some POOL files have for unknown reasons a version
542 // not according to ROOT standards. Hack this explicitly.
543 nb = 1;
544 }
545 }
546 if ( nb < 0 ) {
547 delete pObj;
548 pObj = nullptr;
549 }
550 }
551 return nb;
552 }
553 }
554 return -1;
555 }
556
558 int RootDataConnection::loadRefs( const std::string& section, const std::string& cnt, unsigned long entry,
559 RootObjectRefs& refs )
560 {
561 int nbytes = m_tool->loadRefs( section, cnt, entry, refs );
562 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
563 if ( nbytes < 0 ) {
564 // This is definitely an error:
565 // -- Either branch not preesent at all or
566 // -- ROOT I/O error, which issues -1
567 IIncidentSvc* inc = m_setup->incidentSvc();
568 if ( inc ) {
569 inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) );
570 }
571 }
572 #endif
573 return nbytes;
574 }
575
577 pair<const RootRef*, const RootDataConnection::ContainerSection*>
578 RootDataConnection::getMergeSection( const string& container, int entry ) const
579 {
580 // size_t idx = cont.find('/',1);
581 // string container = cont[0]=='/' ? cont.substr(1,idx==string::npos?idx:idx-1) : cont;
582 auto i = m_mergeSects.find( container );
583 if ( i != m_mergeSects.end() ) {
584 size_t cnt = 0;
585 const ContainerSections& s = ( *i ).second;
586 for ( auto j = s.cbegin(); j != s.cend(); ++j, ++cnt ) {
587 const ContainerSection& c = *j;
588 if ( entry >= c.start && entry < ( c.start + c.length ) ) {
589 if ( m_linkSects.size() > cnt ) {
590 if ( msgSvc().isActive() ) {
591 msgSvc() << MSG::VERBOSE << "MergeSection for:" << container << " [" << entry << "]" << endmsg
592 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
593 }
594 return {&( m_linkSects[cnt] ), &c};
595 }
596 }
597 }
598 }
599 msgSvc() << MSG::DEBUG << "Return INVALID MergeSection for:" << container << " [" << entry << "]" << endmsg
600 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
601 return {nullptr, nullptr};
602 }
603
605 void RootDataConnection::makeRef( IRegistry* pR, RootRef& ref )
606 {
607 IOpaqueAddress* pA = pR->address();
608 makeRef( pR->name(), pA->clID(), pA->svcType(), pA->par()[0], pA->par()[1], -1, ref );
609 }
610
612 void RootDataConnection::makeRef( CSTR name, long clid, int tech, CSTR dbase, CSTR cnt, int entry, RootRef& ref )
613 {
614 string db( dbase );
615 if ( db == m_fid ) db = s_local;
616 ref.entry = entry;
617
618 int cdb = -1;
619 if ( !db.empty() ) {
620 auto idb = std::find_if( m_dbs.begin(), m_dbs.end(), [&]( const std::string& i ) { return i == db; } );
621 cdb = std::distance( m_dbs.begin(), idb );
622 if ( idb == m_dbs.end() ) m_dbs.push_back( db );
623 }
624
625 int ccnt = -1;
626 if ( !cnt.empty() ) {
627 auto icnt = std::find_if( m_conts.begin(), m_conts.end(), [&]( const std::string& i ) { return i == cnt; } );
628 ccnt = std::distance( m_conts.begin(), icnt );
629 if ( icnt == m_conts.end() ) m_conts.push_back( cnt );
630 }
631
632 int clnk = -1;
633 if ( !name.empty() ) {
634 auto ilnk = std::find_if( m_links.begin(), m_links.end(), [&]( const std::string& i ) { return i == name; } );
635 clnk = std::distance( m_links.begin(), ilnk );
636 if ( ilnk == m_links.end() ) m_links.push_back( name );
637 }
638
639 ref.dbase = cdb;
640 ref.container = ccnt;
641 ref.link = clnk;
642 ref.clid = clid;
643 ref.svc = tech;
644 if ( ref.svc == POOL_ROOT_StorageType || ref.svc == POOL_ROOTKEY_StorageType ||
645 ref.svc == POOL_ROOTTREE_StorageType ) {
646 ref.svc = ROOT_StorageType;
647 }
648 }
Gaudi::RootDataConnection::addClient
void addClient(const IInterface *client)
Add new client to this data source.
Definition: RootDataConnection.cpp:152
Gaudi::RootDataConnection::lookupClient
bool lookupClient(const IInterface *client) const
Lookup client for this data source.
Definition: RootDataConnection.cpp:163
Gaudi::RootDataConnection::m_mergeSects
MergeSections m_mergeSects
Database section map for merged files.
Definition: RootDataConnection.h:171
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
StatusCode::SUCCESS
Definition: StatusCode.h:31
std::shared_ptr
std::string::empty
T empty(T...args)
std::distance
T distance(T...args)
IOpaqueAddress::clID
virtual const CLID & clID() const =0
Retrieve class information from link.
Gaudi::IDataConnection::m_age
int m_age
Age counter.
Definition: IIODataManager.h:35
gaudirun.c
c
Definition: gaudirun.py:407
Gaudi::IDataConnection::fid
const std::string & fid() const
Access file id.
Definition: IIODataManager.h:55
LinkManager.h
Gaudi::RootDataConnection::m_tool
std::unique_ptr< Tool > m_tool
Definition: RootDataConnection.h:236
Gaudi::IDataConnection::m_name
std::string m_name
Connection name/identifier.
Definition: IIODataManager.h:29
StatusCode::FAILURE
Definition: StatusCode.h:31
Gaudi::IDataConnection::IoType
IoType
I/O Connection types.
Definition: IIODataManager.h:41
Gaudi::RootDataConnection::saveObj
std::pair< int, unsigned long > saveObj(const std::string &section, const std::string &cnt, TClass *cl, DataObject *pObj, int buff_siz, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
Definition: RootDataConnection.cpp:463
StatusCode::getCode
unsigned long getCode() const
Get the status code by value.
Definition: StatusCode.h:94
MsgStream.h
Gaudi::RootDataConnection::saveStatistics
void saveStatistics(const std::string &statisticsFile)
Save TTree access statistics if required.
Definition: RootDataConnection.cpp:176
std::sscanf
T sscanf(T...args)
Gaudi::RootDataConnection::getDb
const std::string & getDb(int which) const
Access database/file name from saved index.
Definition: RootDataConnection.cpp:450
Gaudi::IDataConnection::m_fid
std::string m_fid
File ID of the connection.
Definition: IIODataManager.h:31
StatusCode::isSuccess
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
Gaudi::RootDataConnection::m_statistics
std::unique_ptr< TTreePerfStats > m_statistics
I/O read statistics from TTree.
Definition: RootDataConnection.h:153
Gaudi::RootDataConnection::loadObj
int loadObj(const std::string &section, const std::string &cnt, unsigned long entry, DataObject *&pObj)
Load object.
Definition: RootDataConnection.cpp:504
std::isalnum
T isalnum(T...args)
Gaudi::RootConnectionSetup::compression
static int compression()
Access to global compression level.
Definition: RootDataConnection.cpp:129
Gaudi::RootDataConnection::m_clients
Clients m_clients
Client list.
Definition: RootDataConnection.h:175
Gaudi::RootDataConnection::ContainerSection::length
int length
The length of the section.
Definition: RootDataConnection.h:128
Gaudi::RootDataConnection::getSection
TTree * getSection(const std::string &sect, bool create=false)
Access TTree section from section name. The section is created if required.
Definition: RootDataConnection.cpp:358
MSG::DEBUG
Definition: IMessageSvc.h:16
Gaudi::RootDataConnection::ContainerSection::start
int start
The start entry of the section.
Definition: RootDataConnection.h:126
Gaudi::RootDataConnection::removeClient
size_t removeClient(const IInterface *client)
Remove client from this data source.
Definition: RootDataConnection.cpp:155
MsgStream::isActive
bool isActive() const
Accessor: is MsgStream active.
Definition: MsgStream.h:116
Gaudi::Utils::Histos::fill
GAUDI_API void fill(AIDA::IHistogram1D *histo, const double value, const double weight=1.0)
simple function to fill AIDA::IHistogram1D objects
Definition: Fill.cpp:35
std
STL namespace.
Gaudi::RootDataConnection::RootDataConnection
RootDataConnection(const IInterface *own, const std::string &nam, std::shared_ptr< RootConnectionSetup > setup)
Standard constructor.
Definition: RootDataConnection.cpp:138
Gaudi::RootRef::container
int container
Definition: RootRefs.h:33
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
std::end
T end(T...args)
std::iota
T iota(T...args)
Gaudi::IDataConnection::RECREATE
Definition: IIODataManager.h:41
Gaudi::RootConnectionSetup::setMessageSvc
void setMessageSvc(MsgStream *m)
Set message service reference.
Definition: RootDataConnection.cpp:132
Gaudi::RootRef::entry
int entry
Definition: RootRefs.h:33
Gaudi::RootDataConnection::connectWrite
StatusCode connectWrite(IoType typ) override
Open data stream in write mode.
Definition: RootDataConnection.cpp:265
MSG::VERBOSE
Definition: IMessageSvc.h:16
IOpaqueAddress::par
virtual const std::string * par() const =0
Retrieve String parameters.
Gaudi::IDataConnection::pfn
const std::string & pfn() const
Access physical file name.
Definition: IIODataManager.h:57
PoolTool.h
Gaudi::RootDataConnection::loadRefs
int loadRefs(const std::string &section, const std::string &cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
Definition: RootDataConnection.cpp:558
Gaudi::RootObjectRefs
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject...
Definition: RootRefs.h:60
Gaudi::RootDataConnection::m_links
StringVec m_links
Map containing internal links names.
Definition: RootDataConnection.h:165
Gaudi::RootDataConnection::m_params
ParamMap m_params
Parameter map for file parameters.
Definition: RootDataConnection.h:169
std::string
STL class.
compareRootHistos.ref
string ref
Definition: compareRootHistos.py:14
POOL_ROOTKEY_StorageType
const long POOL_ROOTKEY_StorageType
Definition: ClassID.h:69
Incident.h
CSTR
const string & CSTR
Definition: RootDataConnection.cpp:39
GaudiPluginService.cpluginsvc.n
n
Definition: cpluginsvc.py:228
Gaudi::RootDataConnection::m_mergeFIDs
StringVec m_mergeFIDs
Map containing merge FIDs.
Definition: RootDataConnection.h:167
Gaudi::IDataConnection::m_pfn
std::string m_pfn
Physical file name of the connection.
Definition: IIODataManager.h:33
Gaudi::RootRef::dbase
int dbase
Data members to define object location in the persistent world.
Definition: RootRefs.h:33
GaudiPython.Persistency.add
def add(instance)
Definition: Persistency.py:39
Gaudi::RootRef
Persistent reference object.
Definition: RootRefs.h:31
std::vector::push_back
T push_back(T...args)
Gaudi::RootDataConnection::ROOT_READ_ERROR
Definition: RootDataConnection.h:97
IIncidentSvc::fireIncident
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
RootTool.h
Gaudi::RootTool
Description:
Definition: RootTool.h:17
DataObject::clID
virtual const CLID & clID() const
Retrieve reference to class definition structure.
Definition: DataObject.cpp:62
Gaudi::IDataConnection::name
const std::string & name() const
Connection name.
Definition: IIODataManager.h:51
std::replace_if
T replace_if(T...args)
IIncidentSvc.h
Gaudi::RootDataConnection::Tool
Helper class to facilitate an abstraction layer for reading POOL style files with this package...
Definition: RootDataConnection.h:195
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
Gaudi::Units::m
constexpr double m
Definition: SystemOfUnits.h:94
MsgStream::clear
void clear(STATE_TYPE _i=std::ios_base::failbit)
Definition: MsgStream.h:187
IInterface
Definition of the basic interface.
Definition: IInterface.h:277
Gaudi::RootDataConnection::getBranch
TBranch * getBranch(const std::string &section, const std::string &branch_name)
Access data branch by name: Get existing branch in read only mode.
Definition: RootDataConnection.h:309
std::runtime_error
STL class.
Gaudi::RootDataConnection::makeRef
void makeRef(IRegistry *pA, RootRef &ref)
Create reference object from registry entry.
Definition: RootDataConnection.cpp:605
std::set::erase
T erase(T...args)
RootUtils.h
Gaudi::RootDataConnection::m_conts
StringVec m_conts
Map containing external container names.
Definition: RootDataConnection.h:163
Gaudi::RootDataConnection::empty
const std::string & empty() const
Empty string reference.
Definition: RootDataConnection.cpp:460
Gaudi::RootDataConnection::m_sections
Sections m_sections
Tree sections in TFile.
Definition: RootDataConnection.h:159
Gaudi::RootDataConnection::getMergeSection
std::pair< const RootRef *, const ContainerSection * > getMergeSection(const std::string &container, int entry) const
Access link section for single container and entry.
Definition: RootDataConnection.cpp:578
IRegistry.h
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
ROOT_StorageType
const long ROOT_StorageType
Definition: ClassID.h:52
RootDataConnection.h
IOpaqueAddress::svcType
virtual long svcType() const =0
Retrieve service type.
std::unique_ptr::reset
T reset(T...args)
std::vector::clear
T clear(T...args)
POOL_ROOT_StorageType
const long POOL_ROOT_StorageType
Definition: ClassID.h:68
Gaudi::RootDataConnection::makeTool
Tool * makeTool()
Create file access tool to encapsulate POOL compatibiliy.
Definition: RootDataConnection.cpp:201
std::move
T move(T...args)
Gaudi::IDataConnection::UPDATE
Definition: IIODataManager.h:41
IOpaqueAddress.h
Gaudi::RootRef::clid
int clid
Definition: RootRefs.h:33
std::pair
Gaudi::RootDataConnection::save
std::pair< int, unsigned long > save(const std::string &section, const std::string &cnt, TClass *cl, void *pObj, int buff_siz, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.
Definition: RootDataConnection.cpp:471
std::unique_ptr::get
T get(T...args)
std::set::insert
T insert(T...args)
std::string::find
T find(T...args)
std::string::length
T length(T...args)
Gaudi::RootDataConnection::connectRead
StatusCode connectRead() override
Open data stream in read mode.
Definition: RootDataConnection.cpp:215
std::vector< std::string >
Gaudi::IDataConnection
ABC describing basic data connection.
Definition: IIODataManager.h:25
Gaudi::RootDataConnection::makeLink
int makeLink(const std::string &p)
Convert path string to path index.
Definition: RootDataConnection.cpp:441
Gaudi::IDataConnection::CREATE
Definition: IIODataManager.h:41
POOL_ROOTTREE_StorageType
const long POOL_ROOTTREE_StorageType
Definition: ClassID.h:70
Gaudi::RootRef::link
int link
Definition: RootRefs.h:33
Gaudi::RootDataConnection::m_setup
std::shared_ptr< RootConnectionSetup > m_setup
Reference to the setup structure.
Definition: RootDataConnection.h:151
std::begin
T begin(T...args)
Gaudi::RootDataConnection::m_linkSects
LinkSections m_linkSects
Database link sections.
Definition: RootDataConnection.h:173
GaudiTesting.BaseTest.which
def which(executable)
Definition: BaseTest.py:570
Gaudi::IDataConnection::resetAge
void resetAge()
Reset age.
Definition: IIODataManager.h:63
std::string::c_str
T c_str(T...args)
Incident
Base class for all Incidents (computing events).
Definition: Incident.h:17
Gaudi::RootDataConnection::msgSvc
MsgStream & msgSvc() const
Allow access to printer service.
Definition: RootDataConnection.h:147
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:8
gaudirun.s
string s
Definition: gaudirun.py:253
std::array
STL class.
Gaudi::RootConnectionSetup::setCompression
static long setCompression(const std::string &compression)
Set the global compression level.
Definition: RootDataConnection.cpp:96
MSG::ERROR
Definition: IMessageSvc.h:16
std::string::substr
T substr(T...args)
gaudirun.level
level
Definition: gaudirun.py:271
Gaudi::RootRef::svc
int svc
Definition: RootRefs.h:33
MSG::WARNING
Definition: IMessageSvc.h:16
Gaudi::RootDataConnection::m_file
std::unique_ptr< TFile > m_file
Reference to ROOT file.
Definition: RootDataConnection.h:155
IOpaqueAddress
Opaque address interface definition.
Definition: IOpaqueAddress.h:23
Gaudi::RootDataConnection::m_dbs
StringVec m_dbs
Map containing external database file names (fids)
Definition: RootDataConnection.h:161
StatusCode::ignore
void ignore() const
Definition: StatusCode.h:109
MSG::INFO
Definition: IMessageSvc.h:16
Gaudi::RootDataConnection::disconnect
StatusCode disconnect() override
Release data stream and release implementation dependent resources.
Definition: RootDataConnection.cpp:325
Gaudi::RootConnectionSetup::setIncidentSvc
void setIncidentSvc(IIncidentSvc *m)
Set incident service reference.
Definition: RootDataConnection.cpp:135
Gaudi::RootDataConnection::enableStatistics
void enableStatistics(const std::string &section)
Enable TTreePerStats.
Definition: RootDataConnection.cpp:186
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:29
Gaudi::RootDataConnection::m_refs
TTree * m_refs
Pointer to the reference tree.
Definition: RootDataConnection.h:157
Gaudi
Helper functions to set/get the application return code.
Definition: __init__.py:1
strcasecmp.h
Gaudi::RootDataConnection::ContainerSection
Internal helper class, which described a TBranch section in a ROOT file.
Definition: RootDataConnection.h:109
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
IIncidentSvc
The interface implemented by the IncidentSvc service.
Definition: IIncidentSvc.h:23
Gaudi::RootDataConnection::badWriteError
void badWriteError(const std::string &msg) const
Error handler when bad write statements occur.
Definition: RootDataConnection.cpp:170
IOTest.evt
evt
Definition: IOTest.py:96
DataObject.h
Gaudi::PoolTool
Definition: PoolTool.h:18
std::vector::emplace_back
T emplace_back(T...args)