The Gaudi Framework  master (e98cfcff)
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
 abstraction layer probably not needed anymore as the only implementation if RootTool 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.
 
 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 162 of file RootDataConnection.cpp.

164 : IDataConnection( owner, std::string{ fname } ), m_setup( std::move( setup ) ) {
165 // 01234567890123456789012345678901234567890
166 // Check if FID: A82A3BD8-7ECB-DC11-8DC0-000423D950B0
167 if ( fname.size() == 36 && fname[8] == '-' && fname[13] == '-' && fname[18] == '-' && fname[23] == '-' ) {
168 m_name = "FID:";
169 m_name.append( fname.data(), fname.size() );
170 }
171 m_age = 0;
172 m_file.reset();
173 addClient( owner );
174}
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 177 of file RootDataConnection.cpp.

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

193 {
194 msgSvc() << MSG::ERROR << "File:" << fid() << "Failed action:" << msg << endmsg;
195}
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 230 of file RootDataConnection.cpp.

230 {
231 m_file.reset( TFile::Open( m_pfn.c_str() ) );
232 if ( !m_file || m_file->IsZombie() ) {
233 m_file.reset();
234 return StatusCode::FAILURE;
235 }
236 StatusCode sc = StatusCode::FAILURE;
237 msgSvc() << MSG::DEBUG << "Opened file " << m_pfn << " in mode READ. [" << m_fid << "]" << endmsg << MSG::DEBUG;
238 if ( msgSvc().isActive() ) m_file->ls();
239 msgSvc() << MSG::VERBOSE;
240 if ( msgSvc().isActive() ) m_file->Print();
241 if ( makeTool() ) {
242 sc = m_tool->readRefs();
243 sc.ignore();
244 if ( sc == Status::ROOT_READ_ERROR ) {
245 IIncidentSvc* inc = m_setup->incidentSvc();
246 if ( inc ) { inc->fireIncident( Incident( pfn(), IncidentType::CorruptedInputFile ) ); }
247 }
248 }
249 if ( !sc.isSuccess() ) return sc;
250 bool need_fid = m_fid == m_pfn;
251 string fid = m_fid;
252 m_mergeFIDs.clear();
253 for ( auto& elem : m_params ) {
254 if ( elem.first == "FID" ) {
255 m_mergeFIDs.push_back( elem.second );
256 if ( elem.second != m_fid ) {
257 msgSvc() << MSG::DEBUG << "Check FID param:" << elem.second << endmsg;
258 // if ( m_fid == m_pfn ) {
259 m_fid = elem.second;
260 //}
261 }
262 }
263 }
264 // Compare uuids in a case insensitive way
265 if ( !need_fid &&
266 !std::ranges::equal( fid, m_fid, []( char a, char b ) { return std::tolower( a ) == std::tolower( b ); } ) ) {
267 msgSvc() << MSG::ERROR << "FID mismatch:" << fid << "(Catalog) != " << m_fid << "(file)" << endmsg
268 << "for PFN:" << m_pfn << endmsg;
269 return StatusCode::FAILURE;
270 }
271 msgSvc() << MSG::DEBUG << "Using FID " << m_fid << " from params table...." << endmsg << "for PFN:" << m_pfn
272 << endmsg;
273 return sc;
274}
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.
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 277 of file RootDataConnection.cpp.

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

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

476{ return s_empty; }

◆ enableStatistics()

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

Enable TTreePerStats.

Definition at line 207 of file RootDataConnection.cpp.

207 {
208 if ( m_statistics ) {
209 TTree* t = getSection( section, false );
210 if ( t ) {
211 m_statistics.reset( new TTreePerfStats( ( std::string{ section } + "_ioperf" ).c_str(), t ) );
212 return;
213 }
214 msgSvc() << MSG::WARNING << "Failed to enable perfstats for tree:" << section << endmsg;
215 return;
216 }
217 msgSvc() << MSG::INFO << "Perfstats are ALREADY ENABLED." << endmsg;
218}
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 260 of file RootDataConnection.h.

260{ 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 322 of file RootDataConnection.h.

322 {
323 return m_tool->getBranch( section, branch_name );
324 }

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

443 {
444 string n = std::string{ branch_name };
445 std::replace_if(
446 begin( n ), end( n ), []( const char c ) { return !isalnum( c ); }, '_' );
447 n += ".";
448 TTree* t = getSection( section, true );
449 TBranch* b = t->GetBranch( n.c_str() );
450 if ( !b && cl && m_file->IsWritable() ) {
451 b = t->Branch( n.c_str(), cl->GetName(), (void*)( ptr ? &ptr : nullptr ), buff_siz, split_lvl );
452 }
453 if ( !b ) b = t->GetBranch( std::string{ branch_name }.c_str() );
454 if ( b ) b->SetAutoDelete( kFALSE );
455 return b;
456}
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 342 of file RootDataConnection.h.

342 {
343 return ( which >= 0 ) && ( size_t( which ) < m_conts.size() ) ? *( m_conts.begin() + which ) : empty();
344 }
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 467 of file RootDataConnection.cpp.

467 {
468 if ( ( which >= 0 ) && ( size_t( which ) < m_dbs.size() ) ) {
469 if ( *( m_dbs.begin() + which ) == s_local ) return m_fid;
470 return *( m_dbs.begin() + which );
471 }
472 return s_empty;
473}
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 347 of file RootDataConnection.h.

347 {
348 return ( which >= 0 ) && ( size_t( which ) < m_links.size() ) ? *( m_links.begin() + which ) : empty();
349 }
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 597 of file RootDataConnection.cpp.

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

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

262{ return bool( m_file ); }

◆ isWritable()

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

Is the file writable?

Definition at line 264 of file RootDataConnection.h.

264{ 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 534 of file RootDataConnection.cpp.

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

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

◆ lookupClient()

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

Lookup client for this data source.

Definition at line 187 of file RootDataConnection.cpp.

187 {
188 auto i = m_clients.find( client );
189 return i != m_clients.end();
190}

◆ makeLink()

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

Convert path string to path index.

Definition at line 459 of file RootDataConnection.cpp.

459 {
460 auto ip = std::find( std::begin( m_links ), std::end( m_links ), p );
461 if ( ip != std::end( m_links ) ) return std::distance( std::begin( m_links ), ip );
462 m_links.push_back( std::string{ p } );
463 return m_links.size() - 1;
464}

◆ makeRef() [1/2]

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

Create reference object from registry entry.

Definition at line 623 of file RootDataConnection.cpp.

623 {
624 IOpaqueAddress* pA = pR.address();
625 makeRef( pR.name(), pA->clID(), pA->svcType(), pA->par()[0], pA->par()[1], -1, ref );
626}
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 629 of file RootDataConnection.cpp.

630 {
631 auto db = ( dbase == m_fid ? std::string_view{ s_local } : dbase );
632 ref.entry = entry;
633
634 int cdb = -1;
635 if ( !db.empty() ) {
636 auto idb = std::find_if( m_dbs.begin(), m_dbs.end(), [&]( const std::string& i ) { return i == db; } );
637 cdb = std::distance( m_dbs.begin(), idb );
638 if ( idb == m_dbs.end() ) m_dbs.push_back( std::string{ db } );
639 }
640
641 int ccnt = -1;
642 if ( !cnt.empty() ) {
643 auto icnt = std::find_if( m_conts.begin(), m_conts.end(), [&]( const std::string& i ) { return i == cnt; } );
644 ccnt = std::distance( m_conts.begin(), icnt );
645 if ( icnt == m_conts.end() ) m_conts.push_back( std::string{ cnt } );
646 }
647
648 int clnk = -1;
649 if ( !name.empty() ) {
650 auto ilnk = std::find_if( m_links.begin(), m_links.end(), [&]( const std::string& i ) { return i == name; } );
651 clnk = std::distance( m_links.begin(), ilnk );
652 if ( ilnk == m_links.end() ) m_links.push_back( std::string{ name } );
653 }
654
655 ref.dbase = cdb;
656 ref.container = ccnt;
657 ref.link = clnk;
658 ref.clid = clid;
659 ref.svc = tech;
660}
const std::string & name() const
Connection name.

◆ makeTool()

RootDataConnection::Tool * RootDataConnection::makeTool ( )

Create file access tool.

Definition at line 220 of file RootDataConnection.cpp.

220 {
221 if ( !m_refs ) m_refs = (TTree*)m_file->Get( "Refs" );
222 if ( m_refs )
223 m_tool.reset( new RootTool( this ) );
224 else
225 m_tool.reset();
226 return m_tool.get();
227}

◆ mergeFIDs()

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

Access merged FIDs.

Definition at line 270 of file RootDataConnection.h.

270{ return m_mergeFIDs; }

◆ mergeSections()

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

Access merged data section inventory.

Definition at line 268 of file RootDataConnection.h.

268{ 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 312 of file RootDataConnection.h.

312{ return StatusCode::FAILURE; }

◆ removeClient()

size_t RootDataConnection::removeClient ( const IInterface * client)

Remove client from this data source.

Definition at line 180 of file RootDataConnection.cpp.

180 {
181 auto i = m_clients.find( client );
182 if ( i != m_clients.end() ) m_clients.erase( i );
183 return m_clients.size();
184}

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

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

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

481 {
482 DataObjectPush push( pObj );
483 return save( section, cnt, cl, pObj, minBufferSize, maxBufferSize, approxEventsPerBasket, split_lvl, fill );
484}
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 198 of file RootDataConnection.cpp.

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

◆ 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 316 of file RootDataConnection.h.

316{ return -1; }

◆ tool()

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

Access tool.

Definition at line 266 of file RootDataConnection.h.

266{ 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 314 of file RootDataConnection.h.

314{ return StatusCode::FAILURE; }

Friends And Related Symbol Documentation

◆ Tool

friend class Tool
friend

Definition at line 250 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 249 of file RootDataConnection.h.


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