The Gaudi Framework  master (1304469f)
Loading...
Searching...
No Matches
Gaudi::RootDataConnection Class Reference

Concrete implementation of the IDataConnection interface to access ROOT files. More...

#include <GaudiRootCnv/RootDataConnection.h>

Inheritance diagram for Gaudi::RootDataConnection:
Collaboration diagram for Gaudi::RootDataConnection:

Classes

class  ContainerSection
 Internal helper class, which described a TBranch section in a ROOT file. More...
 
class  Tool
 Helper class to facilitate an abstraction layer for reading POOL style files with this package. More...
 

Public Types

enum class  Status : StatusCode::code_t { ROOT_READ_ERROR = 0x2 , ROOT_OPEN_ERROR = 0x4 }
 
typedef std::vector< std::string > StringVec
 Type definition for string maps.
 
typedef std::vector< std::pair< std::string, std::string > > ParamMap
 Type definition for the parameter map.
 
typedef std::map< std::string, TTree *, std::less<> > Sections
 Definition of tree sections.
 
typedef std::vector< ContainerSectionContainerSections
 Definition of container sections to handle merged files.
 
typedef std::map< std::string, ContainerSections, std::less<> > MergeSections
 Definition of database section to handle merged files.
 
typedef std::vector< RootRefLinkSections
 Link sections definition.
 
typedef std::set< const IInterface * > Clients
 Client set.
 
- Public Types inherited from Gaudi::IDataConnection
enum  IoType { READ = 1 << 1 , UPDATE = 1 << 2 , CREATE = 1 << 3 , RECREATE = ( 1 << 4 ) + ( 1 << 3 ) }
 I/O Connection types. More...
 
enum  IoStatus { BAD_DATA_CONNECTION = 4 }
 Status Code on bad file connection. More...
 

Public Member Functions

MsgStreammsgSvc () const
 Allow access to printer service.
 
IIncidentSvcincidentSvc () const
 
ToolmakeTool ()
 Create file access tool to encapsulate POOL compatibiliy.
 
 RootDataConnection (const IInterface *own, std::string_view nam, std::shared_ptr< RootConnectionSetup > setup)
 Standard constructor.
 
TFile * file () const
 Direct access to TFile structure.
 
bool isConnected () const override
 Check if connected to data source.
 
bool isWritable () const
 Is the file writable?
 
Tooltool () const
 Access tool.
 
const MergeSectionsmergeSections () const
 Access merged data section inventory.
 
const StringVecmergeFIDs () const
 Access merged FIDs.
 
void addClient (const IInterface *client)
 Add new client to this data source.
 
size_t removeClient (const IInterface *client)
 Remove client from this data source.
 
bool lookupClient (const IInterface *client) const
 Lookup client for this data source.
 
void badWriteError (std::string_view msg) const
 Error handler when bad write statements occur.
 
std::pair< const RootRef *, const ContainerSection * > getMergeSection (std::string_view container, int entry) const
 Access link section for single container and entry.
 
void enableStatistics (std::string_view section)
 Enable TTreePerStats.
 
void saveStatistics (std::string_view statisticsFile)
 Save TTree access statistics if required.
 
int loadObj (std::string_view section, std::string_view cnt, unsigned long entry, DataObject *&pObj)
 Load object.
 
int loadRefs (std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs &refs)
 Load references object.
 
std::pair< int, unsigned long > saveObj (std::string_view section, std::string_view cnt, TClass *cl, DataObject *pObj, int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl, bool fill_missing=false)
 Save object of a given class to section and container.
 
std::pair< int, unsigned long > save (std::string_view section, std::string_view cnt, TClass *cl, void *pObj, int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl, bool fill_missing=false)
 Save object of a given class to section and container.
 
StatusCode connectRead () override
 Open data stream in read mode.
 
StatusCode connectWrite (IoType typ) override
 Open data stream in write mode.
 
StatusCode disconnect () override
 Release data stream and release implementation dependent resources.
 
StatusCode read (void *const, size_t) override
 Read root byte buffer from input stream.
 
StatusCode write (const void *, int) override
 Write root byte buffer to output stream.
 
long long int seek (long long int, int) override
 Seek on the file described by ioDesc. Arguments as in seek()
 
TTree * getSection (std::string_view sect, bool create=false)
 Access TTree section from section name. The section is created if required.
 
TBranch * getBranch (std::string_view section, std::string_view branch_name)
 Access data branch by name: Get existing branch in read only mode.
 
TBranch * getBranch (std::string_view section, std::string_view branch_name, TClass *cl, void *ptr, int buff_siz, int split_lvl)
 Access data branch by name: Get existing branch in write mode.
 
void makeRef (const IRegistry &pA, RootRef &ref)
 Create reference object from registry entry.
 
void makeRef (std::string_view name, long clid, int tech, std::string_view db, std::string_view cnt, int entry, RootRef &ref)
 Create reference object from values.
 
int makeLink (std::string_view p)
 Convert path string to path index.
 
const std::string & getDb (int which) const
 Access database/file name from saved index.
 
const std::string & getCont (int which) const
 Access container name from saved index.
 
const std::string & getLink (int which) const
 Access link name from saved index.
 
- Public Member Functions inherited from Gaudi::IDataConnection
 IDataConnection (const IInterface *own, std::string nam)
 Standard constructor.
 
virtual ~IDataConnection ()=default
 Standard destructor.
 
const std::string & name () const
 Connection name.
 
void setFID (std::string fid)
 Set file ID.
 
const std::string & fid () const
 Access file id.
 
const std::string & pfn () const
 Access physical file name.
 
void setPFN (std::string fn)
 Set physical file name.
 
int ageFile ()
 Increase age of I/O source.
 
void resetAge ()
 Reset age.
 
int age () const
 Access age counter.
 
const IInterfaceowner () const
 Owner instance.
 

Public Attributes

std::unique_ptr< Toolm_tool
 

Protected Member Functions

const std::string & empty () const
 Empty string reference.
 
StatusCode saveRefs ()
 Internal helper to save/update reference tables.
 

Protected Attributes

std::shared_ptr< RootConnectionSetupm_setup
 Reference to the setup structure.
 
std::unique_ptr< TTreePerfStats > m_statistics
 I/O read statistics from TTree.
 
std::unique_ptr< TFile > m_file
 Reference to ROOT file.
 
TTree * m_refs = nullptr
 Pointer to the reference tree.
 
Sections m_sections
 Tree sections in TFile.
 
StringVec m_dbs
 Map containing external database file names (fids)
 
StringVec m_conts
 Map containing external container names.
 
StringVec m_links
 Map containing internal links names.
 
StringVec m_mergeFIDs
 Map containing merge FIDs.
 
ParamMap m_params
 Parameter map for file parameters.
 
MergeSections m_mergeSects
 Database section map for merged files.
 
LinkSections m_linkSects
 Database link sections.
 
Clients m_clients
 Client list.
 
std::string m_empty
 Buffer for empty string reference.
 
- Protected Attributes inherited from Gaudi::IDataConnection
std::string m_name
 Connection name/identifier.
 
std::string m_fid
 File ID of the connection.
 
std::string m_pfn
 Physical file name of the connection.
 
int m_age = 0
 Age counter.
 
const IInterfacem_owner = nullptr
 Owner pointer.
 

Friends

class Tool
 

Detailed Description

Concrete implementation of the IDataConnection interface to access ROOT files.

Author
M.Frank
Version
1.0
Date
20/12/2009

Definition at line 112 of file RootDataConnection.h.

Member Typedef Documentation

◆ Clients

Client set.

Definition at line 160 of file RootDataConnection.h.

◆ ContainerSections

Definition of container sections to handle merged files.

Definition at line 154 of file RootDataConnection.h.

◆ LinkSections

Link sections definition.

Definition at line 158 of file RootDataConnection.h.

◆ MergeSections

typedef std::map<std::string, ContainerSections, std::less<> > Gaudi::RootDataConnection::MergeSections

Definition of database section to handle merged files.

Definition at line 156 of file RootDataConnection.h.

◆ ParamMap

typedef std::vector<std::pair<std::string, std::string> > Gaudi::RootDataConnection::ParamMap

Type definition for the parameter map.

Definition at line 150 of file RootDataConnection.h.

◆ Sections

typedef std::map<std::string, TTree*, std::less<> > Gaudi::RootDataConnection::Sections

Definition of tree sections.

Definition at line 152 of file RootDataConnection.h.

◆ StringVec

typedef std::vector<std::string> Gaudi::RootDataConnection::StringVec

Type definition for string maps.

Definition at line 148 of file RootDataConnection.h.

Member Enumeration Documentation

◆ Status

Enumerator
ROOT_READ_ERROR 
ROOT_OPEN_ERROR 

Definition at line 114 of file RootDataConnection.h.

114: StatusCode::code_t { ROOT_READ_ERROR = 0x2, ROOT_OPEN_ERROR = 0x4 };
unsigned long code_t
type of StatusCode value
Definition StatusCode.h:66

Constructor & Destructor Documentation

◆ RootDataConnection()

RootDataConnection::RootDataConnection ( const IInterface * own,
std::string_view nam,
std::shared_ptr< RootConnectionSetup > setup )

Standard constructor.

Definition at line 165 of file RootDataConnection.cpp.

167 : IDataConnection( owner, std::string{ fname } ), m_setup( std::move( setup ) ) {
168 // 01234567890123456789012345678901234567890
169 // Check if FID: A82A3BD8-7ECB-DC11-8DC0-000423D950B0
170 if ( fname.size() == 36 && fname[8] == '-' && fname[13] == '-' && fname[18] == '-' && fname[23] == '-' ) {
171 m_name = "FID:";
172 m_name.append( fname.data(), fname.size() );
173 }
174 m_age = 0;
175 m_file.reset();
176 addClient( owner );
177}
int m_age
Age counter.
const IInterface * owner() const
Owner instance.
std::string m_name
Connection name/identifier.
IDataConnection(const IInterface *own, std::string nam)
Standard constructor.
void addClient(const IInterface *client)
Add new client to this data source.
std::unique_ptr< TFile > m_file
Reference to ROOT file.
std::shared_ptr< RootConnectionSetup > m_setup
Reference to the setup structure.

Member Function Documentation

◆ addClient()

void RootDataConnection::addClient ( const IInterface * client)

Add new client to this data source.

Definition at line 180 of file RootDataConnection.cpp.

180{ m_clients.insert( client ); }
Clients m_clients
Client list.

◆ badWriteError()

void RootDataConnection::badWriteError ( std::string_view msg) const

Error handler when bad write statements occur.

Definition at line 196 of file RootDataConnection.cpp.

196 {
197 msgSvc() << MSG::ERROR << "File:" << fid() << "Failed action:" << msg << endmsg;
198}
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
const std::string & fid() const
Access file id.
MsgStream & msgSvc() const
Allow access to printer service.
@ ERROR
Definition IMessageSvc.h:22

◆ connectRead()

StatusCode RootDataConnection::connectRead ( )
overridevirtual

Open data stream in read mode.

Connect the file in READ mode.

Implements Gaudi::IDataConnection.

Definition at line 237 of file RootDataConnection.cpp.

237 {
238 m_file.reset( TFile::Open( m_pfn.c_str() ) );
239 if ( !m_file || m_file->IsZombie() ) {
240 m_file.reset();
241 return StatusCode::FAILURE;
242 }
243 StatusCode sc = StatusCode::FAILURE;
244 msgSvc() << MSG::DEBUG << "Opened file " << m_pfn << " in mode READ. [" << m_fid << "]" << endmsg << MSG::DEBUG;
245 if ( msgSvc().isActive() ) m_file->ls();
246 msgSvc() << MSG::VERBOSE;
247 if ( msgSvc().isActive() ) m_file->Print();
248 if ( makeTool() ) {
249 sc = m_tool->readRefs();
250 sc.ignore();
251 if ( sc == Status::ROOT_READ_ERROR ) {
252 IIncidentSvc* inc = m_setup->incidentSvc();
253 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
254 }
255 }
256 if ( !sc.isSuccess() ) return sc;
257 bool need_fid = m_fid == m_pfn;
258 string fid = m_fid;
259 m_mergeFIDs.clear();
260 for ( auto& elem : m_params ) {
261 if ( elem.first == "FID" ) {
262 m_mergeFIDs.push_back( elem.second );
263 if ( elem.second != m_fid ) {
264 msgSvc() << MSG::DEBUG << "Check FID param:" << elem.second << endmsg;
265 // if ( m_fid == m_pfn ) {
266 m_fid = elem.second;
267 //}
268 }
269 }
270 }
271 if ( !need_fid && fid != m_fid ) {
272 msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
273 << "for PFN:" << m_pfn << endmsg;
274 return StatusCode::FAILURE;
275 }
276 msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg << "for PFN:" << m_pfn
277 << endmsg;
278 return sc;
279}
std::string m_fid
File ID of the connection.
std::string m_pfn
Physical file name of the connection.
const std::string & pfn() const
Access physical file name.
Tool * makeTool()
Create file access tool to encapsulate POOL compatibiliy.
std::unique_ptr< Tool > m_tool
ParamMap m_params
Parameter map for file parameters.
StringVec m_mergeFIDs
Map containing merge FIDs.
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
Definition StatusCode.h:139
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto FAILURE
Definition StatusCode.h:100
@ DEBUG
Definition IMessageSvc.h:22
@ VERBOSE
Definition IMessageSvc.h:22

◆ connectWrite()

StatusCode RootDataConnection::connectWrite ( IoType typ)
overridevirtual

Open data stream in write mode.

Implements Gaudi::IDataConnection.

Definition at line 282 of file RootDataConnection.cpp.

282 {
283 int compress = RootConnectionSetup::compression();
284 msgSvc() << MSG::DEBUG;
285 std::string spec = m_pfn;
286 if ( m_setup->produceReproducibleFiles ) spec += "?reproducible"; // https://root.cern.ch/doc/master/classTFile.html
287 switch ( typ ) {
288 case CREATE:
289 resetAge();
290 m_file.reset( TFile::Open( spec.c_str(), "CREATE", "Root event data", compress ) );
291#if ROOT_HAS_630_FWD_COMPAT
292 if ( m_file && m_setup->root630ForwardCompatibility ) m_file->SetBit( TFile::k630forwardCompatibility );
293#endif
294 m_refs = new TTree( "Refs", "Root reference data" );
295 msgSvc() << "Opened file " << m_pfn << " in mode CREATE. [" << m_fid << "]" << endmsg;
296 m_params.emplace_back( "PFN", m_pfn );
297 if ( m_fid != m_pfn ) { m_params.emplace_back( "FID", m_fid ); }
298 makeTool();
299 break;
300 case RECREATE:
301 resetAge();
302 m_file.reset( TFile::Open( spec.c_str(), "RECREATE", "Root event data", compress ) );
303#if ROOT_HAS_630_FWD_COMPAT
304 if ( m_file && m_setup->root630ForwardCompatibility ) m_file->SetBit( TFile::k630forwardCompatibility );
305#endif
306 msgSvc() << "Opened file " << m_pfn << " in mode RECREATE. [" << m_fid << "]" << endmsg;
307 m_refs = new TTree( "Refs", "Root reference data" );
308 m_params.emplace_back( "PFN", m_pfn );
309 if ( m_fid != m_pfn ) { m_params.emplace_back( "FID", m_fid ); }
310 makeTool();
311 break;
312 case UPDATE:
313 resetAge();
314 m_file.reset( TFile::Open( spec.c_str(), "UPDATE", "Root event data", compress ) );
315 msgSvc() << "Opened file " << m_pfn << " in mode UPDATE. [" << m_fid << "]" << endmsg;
316 if ( m_file && !m_file->IsZombie() ) {
317 if ( makeTool() ) {
318 StatusCode sc = m_tool->readRefs();
319 sc.ignore();
320 if ( sc == Status::ROOT_READ_ERROR ) {
321 IIncidentSvc* inc = m_setup->incidentSvc();
322 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
323 }
324 return sc;
325 }
326 TDirectory::TContext ctxt( m_file.get() );
327 m_refs = new TTree( "Refs", "Root reference data" );
328 makeTool();
329 return StatusCode::SUCCESS;
330 }
331 break;
332 default:
333 m_refs = nullptr;
334 m_file.reset();
335 return StatusCode::FAILURE;
336 }
338}
void resetAge()
Reset age.
static int compression()
Access to global compression level.
TTree * m_refs
Pointer to the reference tree.
constexpr static const auto SUCCESS
Definition StatusCode.h:99

◆ disconnect()

StatusCode RootDataConnection::disconnect ( )
overridevirtual

Release data stream and release implementation dependent resources.

Implements Gaudi::IDataConnection.

Definition at line 341 of file RootDataConnection.cpp.

341 {
342 if ( m_file ) {
343 if ( !m_file->IsZombie() ) {
344 if ( m_file->IsWritable() ) {
345 msgSvc() << MSG::DEBUG;
346 TDirectory::TContext ctxt( m_file.get() );
347 if ( m_refs ) {
348 if ( !m_tool->saveRefs().isSuccess() ) badWriteError( "Saving References" );
349 if ( m_refs->Write() < 0 ) badWriteError( "Write Reference branch" );
350 }
351 for ( auto& i : m_sections ) {
352 if ( i.second ) {
353 if ( i.second->Write() < 0 ) badWriteError( "Write section:" + i.first );
354 msgSvc() << "Disconnect section " << i.first << " " << i.second->GetName() << endmsg;
355 }
356 }
357 m_sections.clear();
358 }
359 msgSvc() << MSG::DEBUG;
360 if ( msgSvc().isActive() ) m_file->ls();
361 msgSvc() << MSG::VERBOSE;
362 if ( msgSvc().isActive() ) m_file->Print();
363 m_file->Close();
364 }
365 msgSvc() << MSG::DEBUG << "Disconnected file " << m_pfn << " " << m_file->GetName() << endmsg;
366 m_file.reset();
367 m_tool.reset();
368 }
369 return StatusCode::SUCCESS;
370}
Sections m_sections
Tree sections in TFile.
void badWriteError(std::string_view msg) const
Error handler when bad write statements occur.

◆ empty()

CSTR RootDataConnection::empty ( ) const
protected

Empty string reference.

Definition at line 481 of file RootDataConnection.cpp.

481{ return s_empty; }

◆ enableStatistics()

void RootDataConnection::enableStatistics ( std::string_view section)

Enable TTreePerStats.

Definition at line 210 of file RootDataConnection.cpp.

210 {
211 if ( m_statistics ) {
212 TTree* t = getSection( section, false );
213 if ( t ) {
214 m_statistics.reset( new TTreePerfStats( ( std::string{ section } + "_ioperf" ).c_str(), t ) );
215 return;
216 }
217 msgSvc() << MSG::WARNING << "Failed to enable perfstats for tree:" << section << endmsg;
218 return;
219 }
220 msgSvc() << MSG::INFO << "Perfstats are ALREADY ENABLED." << endmsg;
221}
std::unique_ptr< TTreePerfStats > m_statistics
I/O read statistics from TTree.
TTree * getSection(std::string_view sect, bool create=false)
Access TTree section from section name. The section is created if required.
@ WARNING
Definition IMessageSvc.h:22
@ INFO
Definition IMessageSvc.h:22

◆ file()

TFile * Gaudi::RootDataConnection::file ( ) const
inline

Direct access to TFile structure.

Definition at line 264 of file RootDataConnection.h.

264{ return m_file.get(); }

◆ getBranch() [1/2]

TBranch * Gaudi::RootDataConnection::getBranch ( std::string_view section,
std::string_view branch_name )
inline

Access data branch by name: Get existing branch in read only mode.

Definition at line 326 of file RootDataConnection.h.

326 {
327 return m_tool->getBranch( section, branch_name );
328 }

◆ getBranch() [2/2]

TBranch * RootDataConnection::getBranch ( std::string_view section,
std::string_view branch_name,
TClass * cl,
void * ptr,
int buff_siz,
int split_lvl )

Access data branch by name: Get existing branch in write mode.

Definition at line 447 of file RootDataConnection.cpp.

448 {
449 string n = std::string{ branch_name };
450 std::replace_if(
451 begin( n ), end( n ), []( const char c ) { return !isalnum( c ); }, '_' );
452 n += ".";
453 TTree* t = getSection( section, true );
454 TBranch* b = t->GetBranch( n.c_str() );
455 if ( !b && cl && m_file->IsWritable() ) {
456 b = t->Branch( n.c_str(), cl->GetName(), (void*)( ptr ? &ptr : nullptr ), buff_siz, split_lvl );
457 }
458 if ( !b ) b = t->GetBranch( std::string{ branch_name }.c_str() );
459 if ( b ) b->SetAutoDelete( kFALSE );
460 return b;
461}
AttribStringParser::Iterator begin(const AttribStringParser &parser)

◆ getCont()

const std::string & Gaudi::RootDataConnection::getCont ( int which) const
inline

Access container name from saved index.

Definition at line 346 of file RootDataConnection.h.

346 {
347 return ( which >= 0 ) && ( size_t( which ) < m_conts.size() ) ? *( m_conts.begin() + which ) : empty();
348 }
const std::string & empty() const
Empty string reference.
StringVec m_conts
Map containing external container names.

◆ getDb()

CSTR RootDataConnection::getDb ( int which) const

Access database/file name from saved index.

Definition at line 472 of file RootDataConnection.cpp.

472 {
473 if ( ( which >= 0 ) && ( size_t( which ) < m_dbs.size() ) ) {
474 if ( *( m_dbs.begin() + which ) == s_local ) return m_fid;
475 return *( m_dbs.begin() + which );
476 }
477 return s_empty;
478}
StringVec m_dbs
Map containing external database file names (fids)

◆ getLink()

const std::string & Gaudi::RootDataConnection::getLink ( int which) const
inline

Access link name from saved index.

Definition at line 351 of file RootDataConnection.h.

351 {
352 return ( which >= 0 ) && ( size_t( which ) < m_links.size() ) ? *( m_links.begin() + which ) : empty();
353 }
StringVec m_links
Map containing internal links names.

◆ getMergeSection()

pair< const RootRef *, const RootDataConnection::ContainerSection * > RootDataConnection::getMergeSection ( std::string_view container,
int entry ) const

Access link section for single container and entry.

Definition at line 602 of file RootDataConnection.cpp.

602 {
603 // size_t idx = cont.find('/',1);
604 // string container = cont[0]=='/' ? cont.substr(1,idx==string::npos?idx:idx-1) : cont;
605 auto i = m_mergeSects.find( container );
606 if ( i != m_mergeSects.end() ) {
607 size_t cnt = 0;
608 const ContainerSections& s = ( *i ).second;
609 for ( auto j = s.cbegin(); j != s.cend(); ++j, ++cnt ) {
610 const ContainerSection& c = *j;
611 if ( entry >= c.start && entry < ( c.start + c.length ) ) {
612 if ( m_linkSects.size() > cnt ) {
613 if ( msgSvc().isActive() ) {
614 msgSvc() << MSG::VERBOSE << "MergeSection for:" << container << " [" << entry << "]" << endmsg
615 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
616 }
617 return { &( m_linkSects[cnt] ), &c };
618 }
619 }
620 }
621 }
622 msgSvc() << MSG::DEBUG << "Return INVALID MergeSection for:" << container << " [" << entry << "]" << endmsg
623 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
624 return { nullptr, nullptr };
625}
LinkSections m_linkSects
Database link sections.
std::vector< ContainerSection > ContainerSections
Definition of container sections to handle merged files.
MergeSections m_mergeSects
Database section map for merged files.
Internal helper class, which described a TBranch section in a ROOT file.

◆ getSection()

TTree * RootDataConnection::getSection ( std::string_view sect,
bool create = false )

Access TTree section from section name. The section is created if required.

Definition at line 373 of file RootDataConnection.cpp.

373 {
374 auto it = m_sections.find( section );
375 TTree* t = ( it != m_sections.end() ? it->second : nullptr );
376 if ( !t ) {
377 t = (TTree*)m_file->Get( std::string{ section }.c_str() );
378 if ( !t && create ) {
379 TDirectory::TContext ctxt( m_file.get() );
380 t = new TTree( std::string{ section }.c_str(), "Root data for Gaudi" );
381 }
382 if ( t ) {
383 int cacheSize = m_setup->cacheSize;
384 if ( create ) {
385 // t->SetAutoFlush(100);
386 }
387 if ( section == m_setup->loadSection && cacheSize > -2 ) {
388 MsgStream& msg = msgSvc();
389 int learnEntries = m_setup->learnEntries;
390 t->SetCacheSize( cacheSize );
391 t->SetCacheLearnEntries( learnEntries );
392 msg << MSG::DEBUG;
393 if ( create ) {
394 msg << "Tree:" << section << "Setting up tree cache:" << cacheSize << endmsg;
395 } else {
396 const StringVec& vB = m_setup->vetoBranches;
397 const StringVec& cB = m_setup->cacheBranches;
398 msg << "Tree:" << section << " Setting up tree cache:" << cacheSize << " Add all branches." << endmsg;
399 msg << "Tree:" << section << " Learn for " << learnEntries << " entries." << endmsg;
400
401 if ( cB.empty() && vB.empty() ) {
402 msg << "Adding (default) all branches to tree cache." << endmsg;
403 t->AddBranchToCache( "*", kTRUE );
404 }
405 if ( cB.size() == 1 && cB[0] == "*" ) {
406 msg << "Adding all branches to tree cache according to option \"CacheBranches\"." << endmsg;
407 t->AddBranchToCache( "*", kTRUE );
408 } else {
409 for ( TIter it( t->GetListOfBranches() ); it.Next(); ) {
410 const char* n = ( (TNamed*)( *it ) )->GetName();
411 bool add = false, veto = false;
412 for ( const auto& i : cB ) {
413 if ( !match_wild( n, ( i ).c_str() ) ) continue;
414 add = true;
415 break;
416 }
417 for ( auto i = vB.cbegin(); !add && i != vB.cend(); ++i ) {
418 if ( !match_wild( n, ( *i ).c_str() ) ) continue;
419 veto = true;
420 break;
421 }
422 if ( add && !veto ) {
423 msg << "Add " << n << " to branch cache." << endmsg;
424 t->AddBranchToCache( n, kTRUE );
425 } else {
426 msg << "Do not cache branch " << n << endmsg;
427 }
428 }
429 }
430 }
431 }
432 m_sections[std::string{ section }] = t;
433 } else {
434 // in some rare cases we do have the entry we expect, but we cannot read it
435 // https://gitlab.cern.ch/gaudi/Gaudi/-/issues/301
436 auto key = m_file->GetKey( std::string{ section }.c_str() );
437 if ( key ) {
438 incidentSvc()->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) );
439 msgSvc() << MSG::ERROR << std::format( "failed to get TTree '{}' in {}", section, pfn() ) << endmsg;
440 }
441 }
442 }
443 return t;
444}
std::vector< std::string > StringVec
Type definition for string maps.
IIncidentSvc * incidentSvc() const

◆ incidentSvc()

IIncidentSvc * Gaudi::RootDataConnection::incidentSvc ( ) const
inline

Definition at line 164 of file RootDataConnection.h.

164{ return m_setup->incidentSvc(); }

◆ isConnected()

bool Gaudi::RootDataConnection::isConnected ( ) const
inlineoverridevirtual

Check if connected to data source.

Implements Gaudi::IDataConnection.

Definition at line 266 of file RootDataConnection.h.

266{ return bool( m_file ); }

◆ isWritable()

bool Gaudi::RootDataConnection::isWritable ( ) const
inline

Is the file writable?

Definition at line 268 of file RootDataConnection.h.

268{ return m_file && m_file->IsWritable(); }

◆ loadObj()

int RootDataConnection::loadObj ( std::string_view section,
std::string_view cnt,
unsigned long entry,
DataObject *& pObj )

Load object.

Definition at line 539 of file RootDataConnection.cpp.

540 {
541 TBranch* b = getBranch( section, cnt );
542 if ( b ) {
543 TClass* cl = gROOT->GetClass( b->GetClassName(), kTRUE );
544 if ( cl ) {
545 int nb = -1;
546 pObj = (DataObject*)cl->New();
547 {
548 DataObjectPush push( pObj );
549 b->SetAddress( &pObj );
550 if ( section == m_setup->loadSection ) {
551 TTree* t = b->GetTree();
552 if ( Long64_t( entry ) != t->GetReadEntry() ) { t->LoadTree( Long64_t( entry ) ); }
553 }
554 nb = b->GetEntry( entry );
555 msgSvc() << MSG::VERBOSE;
556 if ( msgSvc().isActive() ) {
557 msgSvc() << "Load [" << entry << "] --> " << section << ":" << cnt << " " << nb << " bytes." << endmsg;
558 }
559 if ( nb < 0 ) { // This is definitely an error...ROOT says if reads fail, -1 is issued.
560 IIncidentSvc* inc = m_setup->incidentSvc();
561 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
562 } else if ( nb == 0 && pObj->clID() == CLID_DataObject ) {
563 TFile* f = b->GetFile();
564 int vsn = f->GetVersion();
565 if ( vsn < 52400 ) {
566 // For Gaudi v21r5 (ROOT 5.24.00b) DataObject::m_version was not written!
567 // Still this call be well be successful.
568 nb = 1;
569 } else if ( vsn > 1000000 && ( vsn % 1000000 ) < 52400 ) {
570 // dto. Some POOL files have for unknown reasons a version
571 // not according to ROOT standards. Hack this explicitly.
572 nb = 1;
573 }
574 }
575 if ( nb < 0 ) {
576 delete pObj;
577 pObj = nullptr;
578 }
579 }
580 return nb;
581 }
582 }
583 return -1;
584}
virtual const CLID & clID() const
Retrieve reference to class definition structure.
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.

◆ loadRefs()

int RootDataConnection::loadRefs ( std::string_view section,
std::string_view cnt,
unsigned long entry,
RootObjectRefs & refs )

Load references object.

Definition at line 587 of file RootDataConnection.cpp.

588 {
589 int nbytes = m_tool->loadRefs( section, cnt, entry, refs );
590 if ( nbytes < 0 ) {
591 // This is definitely an error:
592 // -- Either branch not present at all or
593 // -- ROOT I/O error, which issues -1
594 IIncidentSvc* inc = m_setup->incidentSvc();
595 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
596 }
597 return nbytes;
598}

◆ lookupClient()

bool RootDataConnection::lookupClient ( const IInterface * client) const

Lookup client for this data source.

Definition at line 190 of file RootDataConnection.cpp.

190 {
191 auto i = m_clients.find( client );
192 return i != m_clients.end();
193}

◆ makeLink()

int RootDataConnection::makeLink ( std::string_view p)

Convert path string to path index.

Definition at line 464 of file RootDataConnection.cpp.

464 {
465 auto ip = std::find( std::begin( m_links ), std::end( m_links ), p );
466 if ( ip != std::end( m_links ) ) return std::distance( std::begin( m_links ), ip );
467 m_links.push_back( std::string{ p } );
468 return m_links.size() - 1;
469}

◆ makeRef() [1/2]

void RootDataConnection::makeRef ( const IRegistry & pA,
RootRef & ref )

Create reference object from registry entry.

Definition at line 628 of file RootDataConnection.cpp.

628 {
629 IOpaqueAddress* pA = pR.address();
630 makeRef( pR.name(), pA->clID(), pA->svcType(), pA->par()[0], pA->par()[1], -1, ref );
631}
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
virtual long svcType() const =0
Retrieve service type.
virtual const CLID & clID() const =0
Retrieve class information from link.
virtual const std::string * par() const =0
Retrieve String parameters.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.

◆ makeRef() [2/2]

void RootDataConnection::makeRef ( std::string_view name,
long clid,
int tech,
std::string_view db,
std::string_view cnt,
int entry,
RootRef & ref )

Create reference object from values.

Definition at line 634 of file RootDataConnection.cpp.

635 {
636 auto db = ( dbase == m_fid ? std::string_view{ s_local } : dbase );
637 ref.entry = entry;
638
639 int cdb = -1;
640 if ( !db.empty() ) {
641 auto idb = std::find_if( m_dbs.begin(), m_dbs.end(), [&]( const std::string& i ) { return i == db; } );
642 cdb = std::distance( m_dbs.begin(), idb );
643 if ( idb == m_dbs.end() ) m_dbs.push_back( std::string{ db } );
644 }
645
646 int ccnt = -1;
647 if ( !cnt.empty() ) {
648 auto icnt = std::find_if( m_conts.begin(), m_conts.end(), [&]( const std::string& i ) { return i == cnt; } );
649 ccnt = std::distance( m_conts.begin(), icnt );
650 if ( icnt == m_conts.end() ) m_conts.push_back( std::string{ cnt } );
651 }
652
653 int clnk = -1;
654 if ( !name.empty() ) {
655 auto ilnk = std::find_if( m_links.begin(), m_links.end(), [&]( const std::string& i ) { return i == name; } );
656 clnk = std::distance( m_links.begin(), ilnk );
657 if ( ilnk == m_links.end() ) m_links.push_back( std::string{ name } );
658 }
659
660 ref.dbase = cdb;
661 ref.container = ccnt;
662 ref.link = clnk;
663 ref.clid = clid;
664 ref.svc = tech;
667 ref.svc = ROOT_StorageType;
668 }
669}
const long POOL_ROOTKEY_StorageType
Definition ClassID.h:77
const long POOL_ROOT_StorageType
Definition ClassID.h:76
const long POOL_ROOTTREE_StorageType
Definition ClassID.h:78
const long ROOT_StorageType
Definition ClassID.h:60
const std::string & name() const
Connection name.

◆ makeTool()

RootDataConnection::Tool * RootDataConnection::makeTool ( )

Create file access tool to encapsulate POOL compatibiliy.

Create file access tool to encapsulate POOL compatibility.

Definition at line 224 of file RootDataConnection.cpp.

224 {
225 if ( !m_refs ) m_refs = (TTree*)m_file->Get( "Refs" );
226 if ( m_refs ) m_tool.reset( new RootTool( this ) );
227#ifdef __POOL_COMPATIBILITY
228 else if ( m_file->Get( "##Links" ) != nullptr )
229 m_tool.reset( new PoolTool( this ) );
230#endif
231 else
232 m_tool.reset();
233 return m_tool.get();
234}

◆ mergeFIDs()

const StringVec & Gaudi::RootDataConnection::mergeFIDs ( ) const
inline

Access merged FIDs.

Definition at line 274 of file RootDataConnection.h.

274{ return m_mergeFIDs; }

◆ mergeSections()

const MergeSections & Gaudi::RootDataConnection::mergeSections ( ) const
inline

Access merged data section inventory.

Definition at line 272 of file RootDataConnection.h.

272{ return m_mergeSects; }

◆ msgSvc()

MsgStream & Gaudi::RootDataConnection::msgSvc ( ) const
inline

Allow access to printer service.

Definition at line 163 of file RootDataConnection.h.

163{ return m_setup->msgSvc(); }

◆ read()

StatusCode Gaudi::RootDataConnection::read ( void * const ,
size_t  )
inlineoverridevirtual

Read root byte buffer from input stream.

Implements Gaudi::IDataConnection.

Definition at line 316 of file RootDataConnection.h.

316{ return StatusCode::FAILURE; }

◆ removeClient()

size_t RootDataConnection::removeClient ( const IInterface * client)

Remove client from this data source.

Definition at line 183 of file RootDataConnection.cpp.

183 {
184 auto i = m_clients.find( client );
185 if ( i != m_clients.end() ) m_clients.erase( i );
186 return m_clients.size();
187}

◆ save()

pair< int, unsigned long > RootDataConnection::save ( std::string_view section,
std::string_view cnt,
TClass * cl,
void * pObj,
int minBufferSize,
int maxBufferSize,
int approxEventsPerBasket,
int split_lvl,
bool fill_missing = false )

Save object of a given class to section and container.

Definition at line 492 of file RootDataConnection.cpp.

494 {
495 split_lvl = 0;
496 TBranch* b = getBranch( section, cnt, cl, pObj ? &pObj : nullptr, minBufferSize, split_lvl );
497 if ( b ) {
498 Long64_t evt = b->GetEntries();
499 // msgSvc() << MSG::DEBUG << cnt.c_str() << " Obj:" << (void*)pObj
500 // << " Split:" << split_lvl << " Buffer size:" << minBufferSize << endl;
501 bool set_buffer_size = ( evt == 0 );
502 if ( fill_missing ) {
503 Long64_t num, nevt = b->GetTree()->GetEntries();
504 if ( nevt > evt ) {
505 set_buffer_size = true;
506 b->SetAddress( nullptr );
507 num = nevt - evt;
508 while ( num > 0 ) {
509 b->Fill();
510 --num;
511 }
512 msgSvc() << MSG::DEBUG << "Added " << long( nevt - evt ) << " / Tree: " << nevt
513 << " / Branch: " << b->GetEntries() + 1 << " NULL entries to:" << cnt << endmsg;
514 evt = b->GetEntries();
515 }
516 }
517 if ( set_buffer_size ) {
518 auto dummy_file = make_unique<TMemFile>( "dummy.root", "CREATE" );
519 auto dummy_tree = make_unique<TTree>( "DummyTree", "DummyTree", split_lvl, dummy_file->GetDirectory( "/" ) );
520 TBranch* dummy_branch = dummy_tree->Branch( "DummyBranch", cl->GetName(), &pObj, minBufferSize, split_lvl );
521 Int_t nWritten = dummy_branch->Fill();
522 if ( nWritten < 0 ) return { nWritten, evt };
523 Int_t newBasketSize = nWritten * approxEventsPerBasket;
524 // Ensure that newBasketSize doesn't wrap around
525 if ( std::numeric_limits<Int_t>::max() / approxEventsPerBasket < nWritten ) {
526 newBasketSize = std::numeric_limits<Int_t>::max();
527 }
528 b->SetBasketSize( std::min( maxBufferSize, std::max( minBufferSize, newBasketSize ) ) );
529 msgSvc() << MSG::DEBUG << "Setting basket size to " << newBasketSize << " for " << cnt << endmsg;
530 }
531 b->SetAddress( &pObj );
532 return { b->Fill(), evt };
533 }
534 if ( pObj ) { msgSvc() << MSG::ERROR << "Failed to access branch " << m_name << "/" << cnt << endmsg; }
535 return { -1, ~0 };
536}

◆ saveObj()

pair< int, unsigned long > RootDataConnection::saveObj ( std::string_view section,
std::string_view cnt,
TClass * cl,
DataObject * pObj,
int minBufferSize,
int maxBufferSize,
int approxEventsPerBasket,
int split_lvl,
bool fill_missing = false )

Save object of a given class to section and container.

Definition at line 484 of file RootDataConnection.cpp.

486 {
487 DataObjectPush push( pObj );
488 return save( section, cnt, cl, pObj, minBufferSize, maxBufferSize, approxEventsPerBasket, split_lvl, fill );
489}
std::pair< int, unsigned long > save(std::string_view section, std::string_view cnt, TClass *cl, void *pObj, int minBufferSize, int maxBufferSize, int approxEventsPerBasket, int split_lvl, bool fill_missing=false)
Save object of a given class to section and container.

◆ saveRefs()

StatusCode Gaudi::RootDataConnection::saveRefs ( )
protected

Internal helper to save/update reference tables.

◆ saveStatistics()

void RootDataConnection::saveStatistics ( std::string_view statisticsFile)

Save TTree access statistics if required.

Definition at line 201 of file RootDataConnection.cpp.

201 {
202 if ( m_statistics ) {
203 m_statistics->Print();
204 if ( !statisticsFile.empty() ) m_statistics->SaveAs( std::string{ statisticsFile }.c_str() );
205 m_statistics.reset();
206 }
207}

◆ seek()

long long int Gaudi::RootDataConnection::seek ( long long int ,
int  )
inlineoverridevirtual

Seek on the file described by ioDesc. Arguments as in seek()

Implements Gaudi::IDataConnection.

Definition at line 320 of file RootDataConnection.h.

320{ return -1; }

◆ tool()

Tool * Gaudi::RootDataConnection::tool ( ) const
inline

Access tool.

Definition at line 270 of file RootDataConnection.h.

270{ return m_tool.get(); }

◆ write()

StatusCode Gaudi::RootDataConnection::write ( const void * ,
int  )
inlineoverridevirtual

Write root byte buffer to output stream.

Implements Gaudi::IDataConnection.

Definition at line 318 of file RootDataConnection.h.

318{ return StatusCode::FAILURE; }

Friends And Related Symbol Documentation

◆ Tool

friend class Tool
friend

Definition at line 254 of file RootDataConnection.h.

Member Data Documentation

◆ m_clients

Clients Gaudi::RootDataConnection::m_clients
protected

Client list.

Definition at line 192 of file RootDataConnection.h.

◆ m_conts

StringVec Gaudi::RootDataConnection::m_conts
protected

Map containing external container names.

Definition at line 180 of file RootDataConnection.h.

◆ m_dbs

StringVec Gaudi::RootDataConnection::m_dbs
protected

Map containing external database file names (fids)

Definition at line 178 of file RootDataConnection.h.

◆ m_empty

std::string Gaudi::RootDataConnection::m_empty
protected

Buffer for empty string reference.

Definition at line 194 of file RootDataConnection.h.

◆ m_file

std::unique_ptr<TFile> Gaudi::RootDataConnection::m_file
protected

Reference to ROOT file.

Definition at line 172 of file RootDataConnection.h.

◆ m_links

StringVec Gaudi::RootDataConnection::m_links
protected

Map containing internal links names.

Definition at line 182 of file RootDataConnection.h.

◆ m_linkSects

LinkSections Gaudi::RootDataConnection::m_linkSects
protected

Database link sections.

Definition at line 190 of file RootDataConnection.h.

◆ m_mergeFIDs

StringVec Gaudi::RootDataConnection::m_mergeFIDs
protected

Map containing merge FIDs.

Definition at line 184 of file RootDataConnection.h.

◆ m_mergeSects

MergeSections Gaudi::RootDataConnection::m_mergeSects
protected

Database section map for merged files.

Definition at line 188 of file RootDataConnection.h.

◆ m_params

ParamMap Gaudi::RootDataConnection::m_params
protected

Parameter map for file parameters.

Definition at line 186 of file RootDataConnection.h.

◆ m_refs

TTree* Gaudi::RootDataConnection::m_refs = nullptr
protected

Pointer to the reference tree.

Definition at line 174 of file RootDataConnection.h.

◆ m_sections

Sections Gaudi::RootDataConnection::m_sections
protected

Tree sections in TFile.

Definition at line 176 of file RootDataConnection.h.

◆ m_setup

std::shared_ptr<RootConnectionSetup> Gaudi::RootDataConnection::m_setup
protected

Reference to the setup structure.

Definition at line 168 of file RootDataConnection.h.

◆ m_statistics

std::unique_ptr<TTreePerfStats> Gaudi::RootDataConnection::m_statistics
protected

I/O read statistics from TTree.

Definition at line 170 of file RootDataConnection.h.

◆ m_tool

std::unique_ptr<Tool> Gaudi::RootDataConnection::m_tool

Definition at line 253 of file RootDataConnection.h.


The documentation for this class was generated from the following files: