The Gaudi Framework  master (ff829712)
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 175 of file RootDataConnection.cpp.

177 : IDataConnection( owner, std::string{ fname } ), m_setup( std::move( setup ) ) {
178 // 01234567890123456789012345678901234567890
179 // Check if FID: A82A3BD8-7ECB-DC11-8DC0-000423D950B0
180 if ( fname.size() == 36 && fname[8] == '-' && fname[13] == '-' && fname[18] == '-' && fname[23] == '-' ) {
181 m_name = "FID:";
182 m_name.append( fname.data(), fname.size() );
183 }
184 m_age = 0;
185 m_file.reset();
186 addClient( owner );
187}
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 190 of file RootDataConnection.cpp.

190{ 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 206 of file RootDataConnection.cpp.

206 {
207 msgSvc() << MSG::ERROR << "File:" << fid() << "Failed action:" << msg << endmsg;
208}
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 247 of file RootDataConnection.cpp.

247 {
248 m_file.reset( TFile::Open( m_pfn.c_str() ) );
249 if ( !m_file || m_file->IsZombie() ) {
250 m_file.reset();
251 return StatusCode::FAILURE;
252 }
253 StatusCode sc = StatusCode::FAILURE;
254 msgSvc() << MSG::DEBUG << "Opened file " << m_pfn << " in mode READ. [" << m_fid << "]" << endmsg << MSG::DEBUG;
255 if ( msgSvc().isActive() ) m_file->ls();
256 msgSvc() << MSG::VERBOSE;
257 if ( msgSvc().isActive() ) m_file->Print();
258 if ( makeTool() ) {
259 sc = m_tool->readRefs();
260 sc.ignore();
261#if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
262 if ( sc == Status::ROOT_READ_ERROR ) {
263 IIncidentSvc* inc = m_setup->incidentSvc();
264 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
265 }
266#endif
267 }
268 if ( !sc.isSuccess() ) return sc;
269 bool need_fid = m_fid == m_pfn;
270 string fid = m_fid;
271 m_mergeFIDs.clear();
272 for ( auto& elem : m_params ) {
273 if ( elem.first == "FID" ) {
274 m_mergeFIDs.push_back( elem.second );
275 if ( elem.second != m_fid ) {
276 msgSvc() << MSG::DEBUG << "Check FID param:" << elem.second << endmsg;
277 // if ( m_fid == m_pfn ) {
278 m_fid = elem.second;
279 //}
280 }
281 }
282 }
283 if ( !need_fid && fid != m_fid ) {
284 msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
285 << "for PFN:" << m_pfn << endmsg;
286 return StatusCode::FAILURE;
287 }
288 msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg << "for PFN:" << m_pfn
289 << endmsg;
290 return sc;
291}
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 294 of file RootDataConnection.cpp.

294 {
295 int compress = RootConnectionSetup::compression();
296 msgSvc() << MSG::DEBUG;
297 std::string spec = m_pfn;
298 if ( m_setup->produceReproducibleFiles ) spec += "?reproducible"; // https://root.cern.ch/doc/master/classTFile.html
299 switch ( typ ) {
300 case CREATE:
301 resetAge();
302 m_file.reset( TFile::Open( spec.c_str(), "CREATE", "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 m_refs = new TTree( "Refs", "Root reference data" );
307 msgSvc() << "Opened file " << m_pfn << " in mode CREATE. [" << m_fid << "]" << endmsg;
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 RECREATE:
313 resetAge();
314 m_file.reset( TFile::Open( spec.c_str(), "RECREATE", "Root event data", compress ) );
315#if ROOT_HAS_630_FWD_COMPAT
316 if ( m_file && m_setup->root630ForwardCompatibility ) m_file->SetBit( TFile::k630forwardCompatibility );
317#endif
318 msgSvc() << "Opened file " << m_pfn << " in mode RECREATE. [" << m_fid << "]" << endmsg;
319 m_refs = new TTree( "Refs", "Root reference data" );
320 m_params.emplace_back( "PFN", m_pfn );
321 if ( m_fid != m_pfn ) { m_params.emplace_back( "FID", m_fid ); }
322 makeTool();
323 break;
324 case UPDATE:
325 resetAge();
326 m_file.reset( TFile::Open( spec.c_str(), "UPDATE", "Root event data", compress ) );
327 msgSvc() << "Opened file " << m_pfn << " in mode UPDATE. [" << m_fid << "]" << endmsg;
328 if ( m_file && !m_file->IsZombie() ) {
329 if ( makeTool() ) {
330 StatusCode sc = m_tool->readRefs();
331 sc.ignore();
332 if ( sc == Status::ROOT_READ_ERROR ) {
333#if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
334 IIncidentSvc* inc = m_setup->incidentSvc();
335 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
336#endif
337 }
338 return sc;
339 }
340 TDirectory::TContext ctxt( m_file.get() );
341 m_refs = new TTree( "Refs", "Root reference data" );
342 makeTool();
343 return StatusCode::SUCCESS;
344 }
345 break;
346 default:
347 m_refs = nullptr;
348 m_file.reset();
349 return StatusCode::FAILURE;
350 }
352}
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 355 of file RootDataConnection.cpp.

355 {
356 if ( m_file ) {
357 if ( !m_file->IsZombie() ) {
358 if ( m_file->IsWritable() ) {
359 msgSvc() << MSG::DEBUG;
360 TDirectory::TContext ctxt( m_file.get() );
361 if ( m_refs ) {
362 if ( !m_tool->saveRefs().isSuccess() ) badWriteError( "Saving References" );
363 if ( m_refs->Write() < 0 ) badWriteError( "Write Reference branch" );
364 }
365 for ( auto& i : m_sections ) {
366 if ( i.second ) {
367 if ( i.second->Write() < 0 ) badWriteError( "Write section:" + i.first );
368 msgSvc() << "Disconnect section " << i.first << " " << i.second->GetName() << endmsg;
369 }
370 }
371 m_sections.clear();
372 }
373 msgSvc() << MSG::DEBUG;
374 if ( msgSvc().isActive() ) m_file->ls();
375 msgSvc() << MSG::VERBOSE;
376 if ( msgSvc().isActive() ) m_file->Print();
377 m_file->Close();
378 }
379 msgSvc() << MSG::DEBUG << "Disconnected file " << m_pfn << " " << m_file->GetName() << endmsg;
380 m_file.reset();
381 m_tool.reset();
382 }
383 return StatusCode::SUCCESS;
384}
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 495 of file RootDataConnection.cpp.

495{ return s_empty; }

◆ enableStatistics()

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

Enable TTreePerStats.

Definition at line 220 of file RootDataConnection.cpp.

220 {
221 if ( m_statistics ) {
222 TTree* t = getSection( section, false );
223 if ( t ) {
224 m_statistics.reset( new TTreePerfStats( ( std::string{ section } + "_ioperf" ).c_str(), t ) );
225 return;
226 }
227 msgSvc() << MSG::WARNING << "Failed to enable perfstats for tree:" << section << endmsg;
228 return;
229 }
230 msgSvc() << MSG::INFO << "Perfstats are ALREADY ENABLED." << endmsg;
231}
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 461 of file RootDataConnection.cpp.

462 {
463 string n = std::string{ branch_name };
464 std::replace_if(
465 begin( n ), end( n ), []( const char c ) { return !isalnum( c ); }, '_' );
466 n += ".";
467 TTree* t = getSection( section, true );
468 TBranch* b = t->GetBranch( n.c_str() );
469 if ( !b && cl && m_file->IsWritable() ) {
470 b = t->Branch( n.c_str(), cl->GetName(), (void*)( ptr ? &ptr : nullptr ), buff_siz, split_lvl );
471 }
472 if ( !b ) b = t->GetBranch( std::string{ branch_name }.c_str() );
473 if ( b ) b->SetAutoDelete( kFALSE );
474 return b;
475}
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 486 of file RootDataConnection.cpp.

486 {
487 if ( ( which >= 0 ) && ( size_t( which ) < m_dbs.size() ) ) {
488 if ( *( m_dbs.begin() + which ) == s_local ) return m_fid;
489 return *( m_dbs.begin() + which );
490 }
491 return s_empty;
492}
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 620 of file RootDataConnection.cpp.

620 {
621 // size_t idx = cont.find('/',1);
622 // string container = cont[0]=='/' ? cont.substr(1,idx==string::npos?idx:idx-1) : cont;
623 auto i = m_mergeSects.find( container );
624 if ( i != m_mergeSects.end() ) {
625 size_t cnt = 0;
626 const ContainerSections& s = ( *i ).second;
627 for ( auto j = s.cbegin(); j != s.cend(); ++j, ++cnt ) {
628 const ContainerSection& c = *j;
629 if ( entry >= c.start && entry < ( c.start + c.length ) ) {
630 if ( m_linkSects.size() > cnt ) {
631 if ( msgSvc().isActive() ) {
632 msgSvc() << MSG::VERBOSE << "MergeSection for:" << container << " [" << entry << "]" << endmsg
633 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
634 }
635 return { &( m_linkSects[cnt] ), &c };
636 }
637 }
638 }
639 }
640 msgSvc() << MSG::DEBUG << "Return INVALID MergeSection for:" << container << " [" << entry << "]" << endmsg
641 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
642 return { nullptr, nullptr };
643}
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 387 of file RootDataConnection.cpp.

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

554 {
555 TBranch* b = getBranch( section, cnt );
556 if ( b ) {
557 TClass* cl = gROOT->GetClass( b->GetClassName(), kTRUE );
558 if ( cl ) {
559 int nb = -1;
560 pObj = (DataObject*)cl->New();
561 {
562 DataObjectPush push( pObj );
563 b->SetAddress( &pObj );
564 if ( section == m_setup->loadSection ) {
565 TTree* t = b->GetTree();
566 if ( Long64_t( entry ) != t->GetReadEntry() ) { t->LoadTree( Long64_t( entry ) ); }
567 }
568 nb = b->GetEntry( entry );
569 msgSvc() << MSG::VERBOSE;
570 if ( msgSvc().isActive() ) {
571 msgSvc() << "Load [" << entry << "] --> " << section << ":" << cnt << " " << nb << " bytes." << endmsg;
572 }
573 if ( nb < 0 ) { // This is definitely an error...ROOT says if reads fail, -1 is issued.
574#if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
575 IIncidentSvc* inc = m_setup->incidentSvc();
576 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
577#endif
578 } else if ( nb == 0 && pObj->clID() == CLID_DataObject ) {
579 TFile* f = b->GetFile();
580 int vsn = f->GetVersion();
581 if ( vsn < 52400 ) {
582 // For Gaudi v21r5 (ROOT 5.24.00b) DataObject::m_version was not written!
583 // Still this call be well be successful.
584 nb = 1;
585 } else if ( vsn > 1000000 && ( vsn % 1000000 ) < 52400 ) {
586 // dto. Some POOL files have for unknown reasons a version
587 // not according to ROOT standards. Hack this explicitly.
588 nb = 1;
589 }
590 }
591 if ( nb < 0 ) {
592 delete pObj;
593 pObj = nullptr;
594 }
595 }
596 return nb;
597 }
598 }
599 return -1;
600}
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 603 of file RootDataConnection.cpp.

604 {
605 int nbytes = m_tool->loadRefs( section, cnt, entry, refs );
606#if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 33, 0 )
607 if ( nbytes < 0 ) {
608 // This is definitely an error:
609 // -- Either branch not present at all or
610 // -- ROOT I/O error, which issues -1
611 IIncidentSvc* inc = m_setup->incidentSvc();
612 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
613 }
614#endif
615 return nbytes;
616}

◆ lookupClient()

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

Lookup client for this data source.

Definition at line 200 of file RootDataConnection.cpp.

200 {
201 auto i = m_clients.find( client );
202 return i != m_clients.end();
203}

◆ makeLink()

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

Convert path string to path index.

Definition at line 478 of file RootDataConnection.cpp.

478 {
479 auto ip = std::find( std::begin( m_links ), std::end( m_links ), p );
480 if ( ip != std::end( m_links ) ) return std::distance( std::begin( m_links ), ip );
481 m_links.push_back( std::string{ p } );
482 return m_links.size() - 1;
483}

◆ makeRef() [1/2]

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

Create reference object from registry entry.

Definition at line 646 of file RootDataConnection.cpp.

646 {
647 IOpaqueAddress* pA = pR.address();
648 makeRef( pR.name(), pA->clID(), pA->svcType(), pA->par()[0], pA->par()[1], -1, ref );
649}
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 652 of file RootDataConnection.cpp.

653 {
654 auto db = ( dbase == m_fid ? std::string_view{ s_local } : dbase );
655 ref.entry = entry;
656
657 int cdb = -1;
658 if ( !db.empty() ) {
659 auto idb = std::find_if( m_dbs.begin(), m_dbs.end(), [&]( const std::string& i ) { return i == db; } );
660 cdb = std::distance( m_dbs.begin(), idb );
661 if ( idb == m_dbs.end() ) m_dbs.push_back( std::string{ db } );
662 }
663
664 int ccnt = -1;
665 if ( !cnt.empty() ) {
666 auto icnt = std::find_if( m_conts.begin(), m_conts.end(), [&]( const std::string& i ) { return i == cnt; } );
667 ccnt = std::distance( m_conts.begin(), icnt );
668 if ( icnt == m_conts.end() ) m_conts.push_back( std::string{ cnt } );
669 }
670
671 int clnk = -1;
672 if ( !name.empty() ) {
673 auto ilnk = std::find_if( m_links.begin(), m_links.end(), [&]( const std::string& i ) { return i == name; } );
674 clnk = std::distance( m_links.begin(), ilnk );
675 if ( ilnk == m_links.end() ) m_links.push_back( std::string{ name } );
676 }
677
678 ref.dbase = cdb;
679 ref.container = ccnt;
680 ref.link = clnk;
681 ref.clid = clid;
682 ref.svc = tech;
685 ref.svc = ROOT_StorageType;
686 }
687}
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 234 of file RootDataConnection.cpp.

234 {
235 if ( !m_refs ) m_refs = (TTree*)m_file->Get( "Refs" );
236 if ( m_refs ) m_tool.reset( new RootTool( this ) );
237#ifdef __POOL_COMPATIBILITY
238 else if ( m_file->Get( "##Links" ) != nullptr )
239 m_tool.reset( new PoolTool( this ) );
240#endif
241 else
242 m_tool.reset();
243 return m_tool.get();
244}

◆ 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 193 of file RootDataConnection.cpp.

193 {
194 auto i = m_clients.find( client );
195 if ( i != m_clients.end() ) m_clients.erase( i );
196 return m_clients.size();
197}

◆ 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 506 of file RootDataConnection.cpp.

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

◆ 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 498 of file RootDataConnection.cpp.

500 {
501 DataObjectPush push( pObj );
502 return save( section, cnt, cl, pObj, minBufferSize, maxBufferSize, approxEventsPerBasket, split_lvl, fill );
503}
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 211 of file RootDataConnection.cpp.

211 {
212 if ( m_statistics ) {
213 m_statistics->Print();
214 if ( !statisticsFile.empty() ) m_statistics->SaveAs( std::string{ statisticsFile }.c_str() );
215 m_statistics.reset();
216 }
217}

◆ 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: