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