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