The Gaudi Framework  master (b9786168)
Loading...
Searching...
No Matches
RootCnvSvc.cpp
Go to the documentation of this file.
1/***********************************************************************************\
2* (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3* *
4* This software is distributed under the terms of the Apache version 2 licence, *
5* copied verbatim in the file "LICENSE". *
6* *
7* In applying this licence, CERN does not waive the privileges and immunities *
8* granted to it by virtue of its status as an Intergovernmental Organization *
9* or submit itself to any jurisdiction. *
10\***********************************************************************************/
11//====================================================================
12// RootCnvSvc implementation
13//--------------------------------------------------------------------
14//
15// Description: Implementation of the ROOT data storage
16//
17// Author : M.Frank
18//
19//====================================================================
20
21// Framework include files
22#include "RootUtils.h"
33#include <GaudiKernel/System.h>
34#include <RootCnv/RootAddress.h>
35#include <RootCnv/RootCnvSvc.h>
41#include <RootCnv/RootRefs.h>
42
43using namespace std;
44using namespace Gaudi;
45typedef const string& CSTR;
46
47#define S_OK StatusCode::SUCCESS
48#define S_FAIL StatusCode::FAILURE
49namespace GaudiRoot {
50 bool patchStreamers( MsgStream& log );
51}
52
53namespace {
54 static map<string, TClass*> s_classesNames;
55 static map<CLID, TClass*> s_classesClids;
56} // namespace
57#define MBYTE ( 1024 * 1024 )
58#define kBYTE 1024
59// Standard constructor
62 m_setup->cacheBranches.push_back( "*" );
63 declareProperty( "LoadSection", m_setup->loadSection = "Event" );
64
65 // ROOT Read parameters: must be shared for the entire file!
66 declareProperty( "CacheSize", m_setup->cacheSize = 10 * MBYTE );
67 declareProperty( "LearnEntries", m_setup->learnEntries = 10 );
68 declareProperty( "CacheBranches", m_setup->cacheBranches );
69 declareProperty( "VetoBranches", m_setup->vetoBranches );
70
71 declareProperty( m_setup->produceReproducibleFiles );
72 m_setup->produceReproducibleFiles.setOwnerType<RootCnvSvc>();
73
74 declareProperty( m_setup->root630ForwardCompatibility );
75 m_setup->root630ForwardCompatibility.setOwnerType<RootCnvSvc>();
76}
77
78// Small routine to issue exceptions
80 if ( m_log ) {
81 log() << MSG::ERROR << "Error: " << msg << endmsg;
82 return S_FAIL;
83 }
84 MsgStream m( msgSvc(), name() );
85 m << MSG::ERROR << "Error: " << msg << endmsg;
86 return S_FAIL;
87}
88
89// Initialize the Db data persistency service
91 string cname;
93 if ( !status.isSuccess() ) { return error( "Failed to initialize ConversionSvc base class." ); }
94 m_log.reset( new MsgStream( msgSvc(), name() ) );
95 if ( !m_compression.empty() ) {
96 log() << MSG::INFO << "Setting global ROOT compression to:" << m_compression.value() << endmsg;
97 if ( !( status = RootConnectionSetup::setCompression( m_compression.value() ) ).isSuccess() ) {
98 return error( "Unable to interprete ROOT compression encoding:" + m_compression );
99 }
100 }
101 m_ioMgr = service( "IODataManager" );
102 if ( !m_ioMgr ) return error( "Unable to localize interface from service:IODataManager" );
103 m_incidentSvc = service( "IncidentSvc" );
104 if ( !m_incidentSvc ) return error( "Unable to localize interface from service:IncidentSvc" );
105 m_setup->setMessageSvc( new MsgStream( msgSvc(), name() ) );
106 m_setup->setIncidentSvc( m_incidentSvc.get() );
108 cname = System::typeinfoName( typeid( DataObject ) );
109 m_classDO = TClass::GetClass( cname.c_str() );
110 if ( !m_classDO ) return error( "Unable to load class description for DataObject" );
111 cname = System::typeinfoName( typeid( RootObjectRefs ) );
112 m_classRefs = TClass::GetClass( cname.c_str() );
113 if ( !m_classRefs ) return error( "Unable to load class description for ObjectRefs" );
114 return S_OK;
115}
116
117// Finalize the Db data persistency service
119 log() << MSG::INFO;
120 if ( m_ioMgr ) {
121 IIODataManager::Connections cons = m_ioMgr->connections( nullptr );
122 for ( auto& i : cons ) {
123 auto pc = dynamic_cast<RootDataConnection*>( i );
124 if ( pc ) {
125 if ( pc->owner() == this && !m_ioPerfStats.empty() ) { pc->saveStatistics( m_ioPerfStats.value() ); }
126 if ( pc->lookupClient( this ) ) {
127 size_t num_clients = pc->removeClient( this );
128 if ( num_clients == 0 ) {
129 if ( m_ioMgr->disconnect( pc ).isSuccess() ) {
130 log() << "Disconnected data IO:" << pc->fid() << " [" << pc->pfn() << "]" << endmsg;
131 delete pc;
132 }
133 }
134 }
135 }
136 }
137 m_ioMgr.reset();
138 }
139 m_log.reset();
140 m_incidentSvc.reset();
141 m_setup->setIncidentSvc( nullptr );
143}
144
145// ConversionSvc overload: Create new Converter using factory
146IConverter* RootCnvSvc::createConverter( long typ, const CLID& wanted, const ICnvFactory* ) {
147 if ( wanted == CLID_StatisticsFile )
148 return new RootDatabaseCnv( typ, wanted, serviceLocator().get(), this );
149 else if ( wanted == CLID_StatisticsDirectory )
150 return new RootDirectoryCnv( typ, wanted, serviceLocator().get(), this );
151 else if ( wanted == CLID_RowWiseTuple )
152 return new RootNTupleCnv( typ, wanted, serviceLocator().get(), this );
153 else if ( wanted == CLID_ColumnWiseTuple )
154 return new RootNTupleCnv( typ, wanted, serviceLocator().get(), this );
155 else
156 return new RootConverter( typ, wanted, serviceLocator().get(), this );
157}
158
159// ConversionSvc overload: Load the class (dictionary) for the converter
161 if ( pObject ) {
162 string cname = System::typeinfoName( typeid( *pObject ) );
163 if ( log().level() <= MSG::DEBUG )
164 log() << MSG::DEBUG << "Trying to 'Autoload' dictionary for class " << cname << endmsg;
165 TClass* cl = s_classesNames[cname];
166 if ( nullptr == cl ) {
167 cl = TClass::GetClass( cname.c_str() );
168 if ( cl ) {
169 s_classesNames[cname] = cl;
170 s_classesClids[pObject->clID()] = cl;
171 }
172 }
173 }
174}
175
176// Helper: Get TClass for a given DataObject pointer
177TClass* RootCnvSvc::getClass( DataObject* pObject ) {
178 auto i = s_classesClids.find( pObject->clID() );
179 if ( i != s_classesClids.end() ) return i->second;
180 loadConverter( pObject );
181 i = s_classesClids.find( pObject->clID() );
182 if ( i != s_classesClids.end() ) return i->second;
183
184 string cname = System::typeinfoName( typeid( *pObject ) );
185 throw runtime_error( "Unknown ROOT class for object:" + cname );
186 return nullptr;
187}
188
189// Connect the output file to the service with open mode.
191 StatusCode sc = S_FAIL;
192 m_current = nullptr;
193 m_currSection.clear();
194 if ( ::strncasecmp( openMode.c_str(), "RECREATE", 3 ) == 0 )
196 else if ( ::strncasecmp( openMode.c_str(), "NEW", 1 ) == 0 )
198 else if ( ::strncasecmp( openMode.c_str(), "CREATE", 1 ) == 0 )
200 else if ( ::strncasecmp( openMode.c_str(), "UPDATE", 1 ) == 0 )
202 if ( sc.isSuccess() && m_current && m_current->isConnected() ) { return S_OK; }
203 m_incidentSvc->fireIncident( Incident( dsn, IncidentType::FailOutputFile ) );
204 log() << MSG::ERROR << "The dataset " << dsn << " cannot be opened in mode " << openMode << ". [Invalid mode]"
205 << endmsg;
206 return sc;
207}
208
209// Connect the output file to the service with open mode.
211 try {
212 IDataConnection* c = m_ioMgr->connection( dataset );
213 bool fire_incident = false;
214 *con = nullptr;
215 if ( !c ) {
216 auto connection = std::make_unique<RootDataConnection>( this, dataset, m_setup );
217 StatusCode sc = ( mode != IDataConnection::READ )
218 ? m_ioMgr->connectWrite( connection.get(), IDataConnection::IoType( mode ), "ROOT" )
219 : m_ioMgr->connectRead( false, connection.get() );
220 c = sc.isSuccess() ? m_ioMgr->connection( dataset ) : nullptr;
221 if ( c ) {
222 bool writable = 0 != ( mode & ( IDataConnection::UPDATE | IDataConnection::RECREATE ) );
223 fire_incident = m_incidentEnabled && ( 0 != ( mode & ( IDataConnection::UPDATE | IDataConnection::READ ) ) );
224 if ( writable ) {
225 m_incidentSvc->fireIncident(
226 ContextIncident<TFile*>( connection->pfn(), "CONNECTED_OUTPUT", connection->file() ) );
227 }
228 if ( 0 != ( mode & IDataConnection::READ ) ) {
229 m_incidentSvc->fireIncident(
230 ContextIncident<TFile*>( connection->pfn(), "CONNECTED_INPUT", connection->file() ) );
231 if ( !m_ioPerfStats.empty() ) { connection->enableStatistics( m_setup->loadSection ); }
232 }
233 connection.release();
234 } else {
235 m_incidentSvc->fireIncident( Incident(
236 dataset, mode == IDataConnection::READ ? IncidentType::FailInputFile : IncidentType::FailOutputFile ) );
237 // An error message was already printed by the IODataManager. no need to do it here!
238 return StatusCode::FAILURE;
239 }
240 }
241 RootDataConnection* pc = dynamic_cast<RootDataConnection*>( c );
242 if ( pc ) {
243 if ( !pc->isConnected() )
244 if ( auto sc = pc->connectRead(); !sc ) return sc;
245 *con = pc;
246 pc->resetAge();
247 pc->addClient( this );
248 }
249 if ( *con ) {
250 if ( fire_incident ) {
251 IOpaqueAddress* pAddr = nullptr;
252 string fid = pc->fid();
253 string section = m_recordName[0] == '/' ? m_recordName.value().substr( 1 ) : m_recordName.value();
254 TBranch* b = pc->getBranch( section, m_recordName.value() );
255 if ( b ) {
256 const string par[2] = { fid, m_recordName };
257 unsigned long ipar[2] = { (unsigned long)( *con ), (unsigned long)b->GetEntries() - 1 };
258 for ( int i = 0; i < b->GetEntries(); ++i ) {
259 ipar[1] = i;
260 if ( !pc->mergeFIDs().empty() ) fid = pc->mergeFIDs()[i];
261 if ( !createAddress( repSvcType(), CLID_DataObject, par, ipar, pAddr ).isSuccess() ) {
262 if ( log().level() <= MSG::VERBOSE )
263 log() << MSG::VERBOSE << "Failed to create address for " << m_recordName << " in:" << fid << " ["
264 << pc->fid() << "][" << i << "]" << endmsg;
265 continue;
266 }
267 if ( log().level() <= MSG::VERBOSE )
268 log() << MSG::VERBOSE << "Prepare " << m_recordName << " " << fid << " [" << par[0] << "][" << i << "]"
269 << endmsg;
270 m_incidentSvc->fireIncident( ContextIncident<IOpaqueAddress*>( fid, "FILE_OPEN_READ", pAddr ) );
271 }
272 } else {
273 if ( log().level() <= MSG::VERBOSE )
274 log() << MSG::VERBOSE << "No valid Records " << m_recordName << " present in:" << pc->fid() << endmsg;
275 }
276 }
277
278 // We can remove retired connections, which are no longer used....
279 for ( auto& i : m_ioMgr->connections( this ) ) {
280 if ( i != *con && !i->isConnected() ) {
281 RootDataConnection* pc = dynamic_cast<RootDataConnection*>( i );
282 if ( pc && pc->lookupClient( this ) ) {
283 size_t num_client = pc->removeClient( this );
284 if ( num_client == 0 ) {
285 if ( m_ioMgr->disconnect( pc ).isSuccess() ) {
286 log() << MSG::INFO << "Removed disconnected IO stream:" << pc->fid() << " [" << pc->pfn() << "]"
287 << endmsg;
288 delete pc;
289 }
290 }
291 }
292 }
293 }
294 return S_OK;
295 }
296 m_incidentSvc->fireIncident( Incident( dataset, IncidentType::FailOutputFile ) );
297 return S_FAIL;
298 } catch ( exception& e ) {
299 m_incidentSvc->fireIncident( Incident( dataset, IncidentType::FailOutputFile ) );
300 return error( string( "connectDatabase> Caught exception:" ) + e.what() );
301 } catch ( ... ) {
302 m_incidentSvc->fireIncident( Incident( dataset, IncidentType::FailOutputFile ) );
303 return error( "connectDatabase> Unknown Fatal Exception for " + dataset );
304 }
305}
306
307// Conect output stream (valid until overwritten)
308StatusCode RootCnvSvc::connectOutput( CSTR db_name ) { return connectOutput( db_name, "NEW" ); }
309
310// Commit pending output on open container
311StatusCode RootCnvSvc::commitOutput( CSTR dsn, bool /* doCommit */ ) {
312 if ( m_current ) {
313 size_t len = m_currSection.find( '/', 1 );
314 string section = m_currSection.substr( 1, len == string::npos ? string::npos : len - 1 );
315 TBranch* b = m_current->getBranch( section, m_currSection );
316 if ( b ) {
317 Long64_t evt = b->GetEntries();
318 TTree* t = b->GetTree();
319 TObjArray* a = t->GetListOfBranches();
320 Int_t nb = a->GetEntriesFast();
322 for ( Int_t i = 0; i < nb; ++i ) {
323 TBranch* br_ptr = (TBranch*)a->UncheckedAt( i );
324 Long64_t br_evt = br_ptr->GetEntries();
325 if ( br_evt < evt ) {
326 Long64_t num = evt - br_evt;
327 br_ptr->SetAddress( nullptr );
328 while ( num > 0 ) {
329 br_ptr->Fill();
330 --num;
331 }
332 if ( log().level() <= MSG::DEBUG )
333 log() << MSG::DEBUG << "commit: Added " << long( evt - br_evt ) << " Section: " << evt
334 << " Branch: " << br_ptr->GetEntries() << " RefNo: " << br_ptr->GetEntries() - 1
335 << " NULL entries to:" << br_ptr->GetName() << endmsg;
336 }
337 }
338
339 b->GetTree()->SetEntries( evt );
340 if ( log().level() <= MSG::DEBUG )
341 log() << MSG::DEBUG << "Set section entries of " << m_currSection << " to " << long( evt ) << " entries."
342 << endmsg;
343 } else {
344 return error( "commitOutput> Failed to update entry numbers on " + dsn );
345 }
346 }
347 return S_OK;
348}
349
350// Disconnect from an existing data stream.
352 IDataConnection* c = m_ioMgr->connection( dataset );
353 return c ? m_ioMgr->disconnect( c ) : S_FAIL;
354}
355
356// IAddressCreator implementation: Address creation
357StatusCode RootCnvSvc::createAddress( long typ, const CLID& clid, const string* par, const unsigned long* ip,
358 IOpaqueAddress*& refpAddress ) {
359 refpAddress = new RootAddress( typ, clid, par[0], par[1], ip[0], ip[1] );
360 return S_OK;
361}
362
363// Insert null marker for not existent transient object
364StatusCode RootCnvSvc::createNullRep( const std::string& path ) {
365 size_t len = path.find( '/', 1 );
366 string section = path.substr( 1, len == string::npos ? string::npos : len - 1 );
367 m_current->saveObj( section, path, nullptr, nullptr, m_minBufferSize, m_maxBufferSize, m_approxEventsPerBasket,
368 m_splitLevel );
369 return S_OK;
370}
371
372// Insert null marker for not existent transient object
373StatusCode RootCnvSvc::createNullRef( const std::string& path ) {
374 RootObjectRefs* refs = nullptr;
375 size_t len = path.find( '/', 1 );
376 string section = path.substr( 1, len == string::npos ? string::npos : len - 1 );
377 pair<int, unsigned long> ret = m_current->save( section, path + "#R", nullptr, refs, m_minBufferSize, m_maxBufferSize,
379 if ( log().level() <= MSG::VERBOSE )
380 log() << MSG::VERBOSE << "Writing object:" << path << " " << ret.first << " " << hex << ret.second << dec
381 << " [NULL]" << endmsg;
382 return S_OK;
383}
384
385// Mark an object for write given an object reference
387 refpAddr = nullptr;
388 if ( !pObj ) return error( "createRep> Current Database is invalid!" );
389 CLID clid = pObj->clID();
390 IRegistry* pR = pObj->registry();
391 string p[2] = { m_current->fid(), pR->identifier() };
392 TClass* cl = ( clid == CLID_DataObject ) ? m_classDO : getClass( pObj );
393 size_t len = p[1].find( '/', 1 );
394 string sect = p[1].substr( 1, len == string::npos ? string::npos : len - 1 );
395 pair<int, unsigned long> ret = m_current->saveObj( sect, p[1], cl, pObj, m_minBufferSize, m_maxBufferSize,
397 if ( ret.first > 1 || ( clid == CLID_DataObject && ret.first == 1 ) ) {
398 unsigned long ip[2] = { 0, ret.second };
399 if ( m_currSection.empty() ) m_currSection = p[1];
400 return createAddress( repSvcType(), clid, p, ip, refpAddr );
401 }
402 return error( "Failed to write object data for:" + p[1] );
403}
404
405// Save object references to data file
407 if ( pObj ) {
408 typedef vector<IRegistry*> Leaves;
409 Leaves leaves;
410 RootObjectRefs refs;
411 IRegistry* pR = pObj->registry();
412 auto dataMgr = SmartIF<IDataManagerSvc>{ pR->dataSvc() };
413 if ( dataMgr ) {
414 StatusCode status = dataMgr->objectLeaves( pObj, leaves );
415 if ( status.isSuccess() ) {
416 RootRef ref;
417 const string& id = pR->identifier();
418 size_t len = id.find( '/', 1 );
419 string sect = id.substr( 1, len == string::npos ? string::npos : len - 1 );
420 LinkManager* pLinks = pObj->linkMgr();
421 for ( auto& i : leaves ) {
422 if ( i->address() ) {
423 m_current->makeRef( *i, ref );
424 ref.entry = i->address()->ipar()[1];
425 refs.refs.push_back( ref );
426 }
427 }
428 for ( int i = 0, n = pLinks->size(); i < n; ++i ) {
429 const LinkManager::Link* lnk = pLinks->link( i );
430 int link_id = m_current->makeLink( lnk->path() );
431 refs.links.push_back( link_id );
432 }
433 pair<int, unsigned long> ret = m_current->save( sect, id + "#R", m_classRefs, &refs, m_minBufferSize,
435 if ( ret.first > 1 ) {
436 if ( log().level() <= MSG::DEBUG )
437 log() << MSG::DEBUG << "Writing object:" << id << " " << ret.first << " " << hex << ret.second << dec
438 << endmsg;
439 return S_OK;
440 }
441 }
442 }
443 }
444 return S_FAIL;
445}
446
447// Read existing object. Open transaction in read mode if not active
449 refpObj = nullptr;
450 if ( !pA ) return S_FAIL;
451 RootDataConnection* con = nullptr;
452 const string* par = pA->par();
453 unsigned long* ipar = const_cast<unsigned long*>( pA->ipar() );
455 if ( sc.isSuccess() ) {
456 ipar[0] = (unsigned long)con;
457 DataObject* pObj = nullptr;
458 size_t len = par[1].find( '/', 1 );
459 string section = par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
460
461 int nb = con->loadObj( section, par[1], ipar[1], pObj );
462 if ( nb > 1 || ( nb == 1 && pObj->clID() == CLID_DataObject ) ) {
463 refpObj = pObj;
464 return S_OK;
465 }
466 delete pObj;
467 }
468 string tag = par[0] + ":" + par[1];
469
470 const auto [itr, new_bad] = m_badFiles.insert( tag );
471 if ( new_bad ) { return error( "createObj> Cannot access the object:" + tag ); }
472 return S_FAIL;
473}
474
475// Resolve the references of the created transient object.
477 if ( !pA || !pObj ) return error( "read> Cannot read object -- no valid object address present " );
478
479 const unsigned long* ipar = pA->ipar();
480 RootDataConnection* con = (RootDataConnection*)ipar[0];
481 if ( con ) {
482 RootObjectRefs refs;
483 const string* par = pA->par();
484 size_t len = par[1].find( '/', 1 );
485 string section = par[1].substr( 1, len == string::npos ? string::npos : len - 1 );
486 int nb = con->loadRefs( section, par[1], ipar[1], refs );
487 if ( nb >= 1 ) {
488 string npar[3];
489 unsigned long nipar[2];
490 IRegistry* pR = pObj->registry();
491 auto dataMgr = SmartIF<IDataManagerSvc>{ pR->dataSvc() };
492 LinkManager* mgr = pObj->linkMgr();
493 for ( const auto& i : refs.links ) mgr->addLink( con->getLink( i ), nullptr );
494 for ( auto& r : refs.refs ) {
495 npar[0] = con->getDb( r.dbase );
496 npar[1] = con->getCont( r.container );
497 npar[2] = con->getLink( r.link );
498 nipar[0] = 0;
499 nipar[1] = r.entry;
500 IOpaqueAddress* nPA = nullptr;
501 StatusCode sc = addressCreator()->createAddress( r.svc, r.clid, npar, nipar, nPA );
502 if ( sc.isSuccess() ) {
503 if ( log().level() <= MSG::VERBOSE )
504 log() << MSG::VERBOSE << dataMgr.as<IService>()->name() << " -> Register:" << pA->registry()->identifier()
505 << "#" << npar[2] << "[" << r.entry << "]" << endmsg;
506 sc = dataMgr->registerAddress( pA->registry(), npar[2], nPA );
507 if ( sc.isSuccess() ) continue;
508 }
509 log() << MSG::ERROR << con->fid() << ": Failed to create address!!!!" << endmsg;
510 return S_FAIL;
511 }
512 return pObj->update();
513 } else if ( nb < 0 ) {
514 string tag = par[0] + ":" + par[1];
515
516 const auto [itr, new_bad] = m_badFiles.insert( tag );
517 if ( new_bad ) { return error( "createObj> Cannot access the object:" + tag + " [Corrupted file]" ); }
518 }
519 }
520 return S_FAIL;
521}
unsigned int CLID
Class ID definition.
Definition ClassID.h:16
const long ROOT_StorageType
Definition ClassID.h:60
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
const std::string CSTR
#define MBYTE
#define S_OK
#define S_FAIL
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & msg() const
shortcut for the method msgStream(MSG::INFO)
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
StatusCode finalize() override
stop the service.
SmartIF< IAddressCreator > & addressCreator() const override
Retrieve address creator facility.
StatusCode initialize() override
Initialize the service.
ConversionSvc(const std::string &name, ISvcLocator *svc, long type)
Standard Constructor.
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
IRegistry * registry() const
Get pointer to Registry.
Definition DataObject.h:79
LinkManager * linkMgr()
Retrieve Link manager.
Definition DataObject.h:81
virtual const CLID & clID() const
Retrieve reference to class definition structure.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
ABC describing basic data connection.
const std::string & fid() const
Access file id.
IoType
I/O Connection types.
std::vector< Connection * > Connections
Description:
Definition RootAddress.h:45
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
TClass * m_classDO
TClass pointer to DataObject class.
Definition RootCnvSvc.h:91
StatusCode connectOutput(const std::string &outputFile, const std::string &openMode) override
Connect the output file to the service with open mode.
virtual StatusCode createNullRef(const std::string &path)
Insert null marker for not existent transient object.
Gaudi::Property< int > m_approxEventsPerBasket
Definition RootCnvSvc.h:76
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
Definition RootCnvSvc.h:85
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.
MsgStream & log() const
Helper: Use message streamer.
Definition RootCnvSvc.h:106
virtual StatusCode i__createRep(DataObject *pObj, IOpaqueAddress *&refpAddr)
Convert the transient object to the requested persistent representation.
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
Gaudi::Property< int > m_maxBufferSize
Definition RootCnvSvc.h:74
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
Gaudi::Property< bool > m_incidentEnabled
Definition RootCnvSvc.h:67
Gaudi::Property< int > m_splitLevel
Definition RootCnvSvc.h:78
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
Definition RootCnvSvc.h:87
StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress) override
IAddressCreator implementation: Address creation.
StatusCode finalize() override
ConversionSvc overload: Finalize Db service.
TClass * m_classRefs
TClass pointer to reference class.
Definition RootCnvSvc.h:89
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
Definition RootCnvSvc.h:83
StatusCode initialize() override
ConversionSvc overload: initialize Db service.
IConverter * createConverter(long typ, const CLID &wanted, const ICnvFactory *fac) override
ConversionSvc overload: Create new Converter using factory.
RootCnvSvc(const std::string &name, ISvcLocator *svc)
Standard constructor.
std::string m_currSection
Property: ROOT section name.
Definition RootCnvSvc.h:95
Gaudi::Property< std::string > m_compression
Definition RootCnvSvc.h:79
StatusCode commitOutput(const std::string &outputFile, bool do_commit) override
Commit pending output.
std::shared_ptr< RootConnectionSetup > m_setup
Setup structure (ref-counted) and passed to data connections.
Definition RootCnvSvc.h:93
Gaudi::Property< std::string > m_ioPerfStats
Definition RootCnvSvc.h:63
virtual StatusCode createNullRep(const std::string &path)
Insert null marker for not existent transient object.
Gaudi::Property< std::string > m_recordName
Definition RootCnvSvc.h:68
std::unique_ptr< MsgStream > m_log
Message streamer.
Definition RootCnvSvc.h:101
Gaudi::Property< int > m_minBufferSize
Definition RootCnvSvc.h:72
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
void loadConverter(DataObject *pObj) override
ConversionSvc overload: Load the class (dictionary) for the converter.
std::set< std::string > m_badFiles
Set with bad files/tables.
Definition RootCnvSvc.h:98
virtual StatusCode i__createObj(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create transient object from persistent data.
static StatusCode setCompression(std::string_view compression)
Set the global compression level.
Description: Definition of the ROOT data converter.
Concrete implementation of the IDataConnection interface to access ROOT files.
const std::string & getLink(int which) const
Access link name from saved index.
bool isConnected() const override
Check if connected to data source.
const std::string & getDb(int which) const
Access database/file name from saved index.
int loadRefs(std::string_view section, std::string_view cnt, unsigned long entry, RootObjectRefs &refs)
Load references object.
int loadObj(std::string_view section, std::string_view cnt, unsigned long entry, DataObject *&pObj)
Load object.
const std::string & getCont(int which) const
Access container name from saved index.
Statistics file converter class definition.
Description: NTuple directory converter class definition Definition of the converter to manage the di...
NTuple converter class definition for NTuples writted/read using ROOT.
virtual StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ipar, IOpaqueAddress *&refpAddress)=0
Create a Generic address using explicit arguments to identify a single object.
The data converters are responsible to translate data from one representation into another.
Definition IConverter.h:65
virtual void fireIncident(const Incident &incident)=0
Fire an Incident.
Opaque address interface definition.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const std::string * par() const =0
Retrieve String parameters.
virtual IRegistry * registry() const =0
Update branch name.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition IRegistry.h:29
virtual const id_type & identifier() const =0
Full identifier (or key)
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
General service interface definition.
Definition IService.h:26
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Base class for all Incidents (computing events).
Definition Incident.h:24
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
SmartIF< ISvcLocator > & serviceLocator() const override
Retrieve pointer to service locator.
Definition Service.cpp:336
const std::string & name() const override
Retrieve name of the service.
Definition Service.cpp:333
Gaudi::Details::PropertyBase * declareProperty(const std::string &name, ToolHandle< T > &hndl, const std::string &doc="none")
Definition Service.h:91
SmartIF< IFace > service(const std::string &name, bool createIf=true) const
Definition Service.h:79
Small smart pointer class with automatic reference counting for IInterface.
Definition SmartIF.h:28
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto FAILURE
Definition StatusCode.h:100
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
Definition __init__.py:1
bool patchStreamers(MsgStream &log)
@ DEBUG
Definition IMessageSvc.h:22
@ ERROR
Definition IMessageSvc.h:22
@ INFO
Definition IMessageSvc.h:22
@ VERBOSE
Definition IMessageSvc.h:22
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Definition System.cpp:260
STL namespace.
Persistent reference object containing all leafs and links corresponding to a Gaudi DataObject.
Definition extractEvt.C:81
std::vector< int > links
The links of the link manager.
Definition RootRefs.h:69
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
Definition RootRefs.h:71
Persistent reference object.
Definition extractEvt.C:44