The Gaudi Framework  master (34daa81a)
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 // Compare uuids in a case insensitive way
272 if ( !need_fid &&
273 !std::ranges::equal( fid, m_fid, []( char a, char b ) { return std::tolower( a ) == std::tolower( b ); } ) ) {
274 msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
275 << "for PFN:" << m_pfn << endmsg;
276 return StatusCode::FAILURE;
277 }
278 msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg << "for PFN:" << m_pfn
279 << endmsg;
280 return sc;
281}
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 284 of file RootDataConnection.cpp.

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

343 {
344 if ( m_file ) {
345 if ( !m_file->IsZombie() ) {
346 if ( m_file->IsWritable() ) {
347 msgSvc() << MSG::DEBUG;
348 TDirectory::TContext ctxt( m_file.get() );
349 if ( m_refs ) {
350 if ( !m_tool->saveRefs().isSuccess() ) badWriteError( "Saving References" );
351 if ( m_refs->Write() < 0 ) badWriteError( "Write Reference branch" );
352 }
353 for ( auto& i : m_sections ) {
354 if ( i.second ) {
355 if ( i.second->Write() < 0 ) badWriteError( "Write section:" + i.first );
356 msgSvc() << "Disconnect section " << i.first << " " << i.second->GetName() << endmsg;
357 }
358 }
359 m_sections.clear();
360 }
361 msgSvc() << MSG::DEBUG;
362 if ( msgSvc().isActive() ) m_file->ls();
363 msgSvc() << MSG::VERBOSE;
364 if ( msgSvc().isActive() ) m_file->Print();
365 m_file->Close();
366 }
367 msgSvc() << MSG::DEBUG << "Disconnected file " << m_pfn << " " << m_file->GetName() << endmsg;
368 m_file.reset();
369 m_tool.reset();
370 }
371 return StatusCode::SUCCESS;
372}
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 483 of file RootDataConnection.cpp.

483{ 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 449 of file RootDataConnection.cpp.

450 {
451 string n = std::string{ branch_name };
452 std::replace_if(
453 begin( n ), end( n ), []( const char c ) { return !isalnum( c ); }, '_' );
454 n += ".";
455 TTree* t = getSection( section, true );
456 TBranch* b = t->GetBranch( n.c_str() );
457 if ( !b && cl && m_file->IsWritable() ) {
458 b = t->Branch( n.c_str(), cl->GetName(), (void*)( ptr ? &ptr : nullptr ), buff_siz, split_lvl );
459 }
460 if ( !b ) b = t->GetBranch( std::string{ branch_name }.c_str() );
461 if ( b ) b->SetAutoDelete( kFALSE );
462 return b;
463}
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 474 of file RootDataConnection.cpp.

474 {
475 if ( ( which >= 0 ) && ( size_t( which ) < m_dbs.size() ) ) {
476 if ( *( m_dbs.begin() + which ) == s_local ) return m_fid;
477 return *( m_dbs.begin() + which );
478 }
479 return s_empty;
480}
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 604 of file RootDataConnection.cpp.

604 {
605 // size_t idx = cont.find('/',1);
606 // string container = cont[0]=='/' ? cont.substr(1,idx==string::npos?idx:idx-1) : cont;
607 auto i = m_mergeSects.find( container );
608 if ( i != m_mergeSects.end() ) {
609 size_t cnt = 0;
610 const ContainerSections& s = ( *i ).second;
611 for ( auto j = s.cbegin(); j != s.cend(); ++j, ++cnt ) {
612 const ContainerSection& c = *j;
613 if ( entry >= c.start && entry < ( c.start + c.length ) ) {
614 if ( m_linkSects.size() > cnt ) {
615 if ( msgSvc().isActive() ) {
616 msgSvc() << MSG::VERBOSE << "MergeSection for:" << container << " [" << entry << "]" << endmsg
617 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
618 }
619 return { &( m_linkSects[cnt] ), &c };
620 }
621 }
622 }
623 }
624 msgSvc() << MSG::DEBUG << "Return INVALID MergeSection for:" << container << " [" << entry << "]" << endmsg
625 << "FID:" << m_fid << " -> PFN:" << m_pfn << endmsg;
626 return { nullptr, nullptr };
627}
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 375 of file RootDataConnection.cpp.

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

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

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

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

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

◆ makeRef() [1/2]

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

Create reference object from registry entry.

Definition at line 630 of file RootDataConnection.cpp.

630 {
631 IOpaqueAddress* pA = pR.address();
632 makeRef( pR.name(), pA->clID(), pA->svcType(), pA->par()[0], pA->par()[1], -1, ref );
633}
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 636 of file RootDataConnection.cpp.

637 {
638 auto db = ( dbase == m_fid ? std::string_view{ s_local } : dbase );
639 ref.entry = entry;
640
641 int cdb = -1;
642 if ( !db.empty() ) {
643 auto idb = std::find_if( m_dbs.begin(), m_dbs.end(), [&]( const std::string& i ) { return i == db; } );
644 cdb = std::distance( m_dbs.begin(), idb );
645 if ( idb == m_dbs.end() ) m_dbs.push_back( std::string{ db } );
646 }
647
648 int ccnt = -1;
649 if ( !cnt.empty() ) {
650 auto icnt = std::find_if( m_conts.begin(), m_conts.end(), [&]( const std::string& i ) { return i == cnt; } );
651 ccnt = std::distance( m_conts.begin(), icnt );
652 if ( icnt == m_conts.end() ) m_conts.push_back( std::string{ cnt } );
653 }
654
655 int clnk = -1;
656 if ( !name.empty() ) {
657 auto ilnk = std::find_if( m_links.begin(), m_links.end(), [&]( const std::string& i ) { return i == name; } );
658 clnk = std::distance( m_links.begin(), ilnk );
659 if ( ilnk == m_links.end() ) m_links.push_back( std::string{ name } );
660 }
661
662 ref.dbase = cdb;
663 ref.container = ccnt;
664 ref.link = clnk;
665 ref.clid = clid;
666 ref.svc = tech;
669 ref.svc = ROOT_StorageType;
670 }
671}
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 494 of file RootDataConnection.cpp.

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

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

488 {
489 DataObjectPush push( pObj );
490 return save( section, cnt, cl, pObj, minBufferSize, maxBufferSize, approxEventsPerBasket, split_lvl, fill );
491}
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: