12 #include "GaudiKernel/MsgStream.h"
13 #include "GaudiKernel/IRegistry.h"
14 #include "GaudiKernel/IUpdateable.h"
15 #include "GaudiKernel/IIncidentSvc.h"
16 #include "GaudiKernel/IDataManagerSvc.h"
17 #include "GaudiKernel/IDataProviderSvc.h"
18 #include "GaudiKernel/KeyedContainer.h"
19 #include "GaudiKernel/DataIncident.h"
20 #include "GaudiKernel/LinkManager.h"
21 #include "GaudiKernel/Incident.h"
22 #include "GaudiKernel/System.h"
23 #include "GaudiUtils/IIODataManager.h"
24 #include "RootCnv/RootRefs.h"
25 #include "RootCnv/RootCnvSvc.h"
26 #include "RootCnv/RootAddress.h"
27 #include "RootCnv/RootConverter.h"
28 #include "RootCnv/RootDatabaseCnv.h"
29 #include "RootCnv/RootDirectoryCnv.h"
30 #include "RootCnv/RootNTupleCnv.h"
31 #include "RootCnv/RootDataConnection.h"
35 using namespace Gaudi;
36 typedef const string&
CSTR;
38 #define S_OK StatusCode::SUCCESS
39 #define S_FAIL StatusCode::FAILURE
43 static map<string, TClass*> s_classesNames;
44 static map<CLID, TClass*> s_classesClids;
46 #define MBYTE 1024*1024
52 m_classRefs = m_classDO = 0;
54 m_setup->cacheBranches.push_back(
"*");
55 declareProperty(
"IOPerfStats", m_ioPerfStats);
56 declareProperty(
"ShareFiles", m_shareFiles =
"NO");
57 declareProperty(
"EnableIncident", m_incidentEnabled =
true);
58 declareProperty(
"RecordsName", m_recordName =
"/FileRecords");
59 declareProperty(
"LoadSection", m_setup->loadSection =
"Event");
62 declareProperty(
"AutoFlush", m_autoFlush = 100);
63 declareProperty(
"BasketSize", m_basketSize = 2*
MBYTE);
64 declareProperty(
"BufferSize", m_bufferSize = 2*
kBYTE);
65 declareProperty(
"SplitLevel", m_splitLevel = 0);
66 declareProperty(
"GlobalCompression",m_compression);
69 declareProperty(
"CacheSize", m_setup->cacheSize = 10*
MBYTE);
70 declareProperty(
"LearnEntries", m_setup->learnEntries = 10);
71 declareProperty(
"CacheBranches", m_setup->cacheBranches);
72 declareProperty(
"VetoBranches", m_setup->vetoBranches);
76 RootCnvSvc::~RootCnvSvc() {
96 return error(
"Failed to initialize ConversionSvc base class.");
105 m_ioMgr = service(
"IODataManager");
107 return error(
"Unable to localize interface from service:IODataManager");
110 return error(
"Unable to localize interface from service:IncidentSvc");
115 m_classDO = TClass::GetClass(cname.c_str());
117 return error(
"Unable to load class description for DataObject");
121 return error(
"Unable to load class description for ObjectRefs");
130 for(
auto &
i : cons ) {
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;
158 if ( wanted == CLID_StatisticsFile )
160 else if ( wanted == CLID_StatisticsDirectory )
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);
167 return new RootConverter(typ,wanted,serviceLocator().
get(),
this);
176 TClass* cl = s_classesNames[cname];
178 cl = TClass::GetClass(cname.c_str());
180 s_classesNames[cname] = cl;
181 s_classesClids[pObject->
clID()] = cl;
189 auto i=s_classesClids.find(pObject->
clID());
190 if (
i != s_classesClids.end() )
return i->second;
192 i=s_classesClids.find(pObject->
clID());
193 if (
i != s_classesClids.end() )
return i->second;
196 throw runtime_error(
"Unknown ROOT class for object:"+cname);
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 )
217 log() <<
MSG::ERROR <<
"The dataset " << dsn <<
" cannot be opened in mode "
218 << openMode <<
". [Invalid mode]" <<
endmsg;
227 bool fire_incident =
false;
233 :
m_ioMgr->connectRead(
false,connection.get());
246 connection.release();
264 if ( fire_incident ) {
266 string fid = pc->
fid();
271 unsigned long ipar[2] = { (
unsigned long)(*con), (
unsigned long)b->GetEntries()-1 };
272 for(
int i=0;
i<b->GetEntries(); ++
i) {
279 <<
" [" << pc->
fid() <<
"][" <<
i <<
"]" <<
endmsg;
294 for(
auto &
i :
m_ioMgr->connections(
this) ) {
295 if (
i != *con && !
i->isConnected() ) {
299 if ( num_client == 0 ) {
300 if (
m_ioMgr->disconnect(pc).isSuccess() ) {
314 catch (exception& e) {
316 return error(
string(
"connectDatabase> Caught exception:")+e.what());
320 return error(
"connectDatabase> Unknown Fatal Exception for "+dataset);
333 string section =
m_currSection.substr(1,len==string::npos ? string::npos : len-1);
336 Long64_t
evt = b->GetEntries();
337 TTree* t = b->GetTree();
338 TObjArray* a = t->GetListOfBranches();
339 Int_t nb = a->GetEntriesFast();
341 for(Int_t
i=0;
i<nb; ++
i) {
342 TBranch* br_ptr = (TBranch*)a->UncheckedAt(
i);
343 Long64_t br_evt = br_ptr->GetEntries();
344 if ( br_evt < evt ) {
345 Long64_t num = evt-br_evt;
346 br_ptr->SetAddress(
nullptr);
352 <<
"commit: Added " << long(evt-br_evt)
353 <<
" Section: " << evt <<
" Branch: " << br_ptr->GetEntries()
354 <<
" RefNo: " << br_ptr->GetEntries()-1
355 <<
" NULL entries to:" << br_ptr->GetName() <<
endmsg;
359 b->GetTree()->SetEntries(evt);
364 if ( evt == m_autoFlush ) {
365 b->GetTree()->SetAutoFlush(m_autoFlush);
369 b->GetTree()->FlushBaskets();
374 <<
" to " << long(evt) <<
" entries." <<
endmsg;
377 return error(
"commitOutput> Failed to update entry numbers on "+dsn);
393 const unsigned long* ip,
396 refpAddress =
new RootAddress(typ,clid,par[0],par[1],ip[0],ip[1]);
402 size_t len = path.find(
'/',1);
403 string section = path.substr(1,len==string::npos ? string::npos : len-1);
411 size_t len = path.find(
'/',1);
412 string section = path.substr(1,len==string::npos ? string::npos : len-1);
413 pair<int,unsigned long> ret =
417 << ret.first <<
" " << hex << ret.second << dec <<
" [NULL]" <<
endmsg;
429 size_t len = p[1].find(
'/',1);
430 string sect = p[1].substr(1,len==string::npos ? string::npos : len-1);
431 pair<int,unsigned long> ret =
433 if ( ret.first > 1 || (clid == CLID_DataObject && ret.first==1) ) {
434 unsigned long ip[2] = {0,ret.second};
438 return error(
"Failed to write object data for:"+p[1]);
440 return error(
"createRep> Current Database is invalid!");
446 typedef vector<IRegistry*> Leaves;
452 StatusCode status = dataMgr->objectLeaves(pObj, leaves);
456 size_t len =
id.find(
'/',1);
457 string sect =
id.substr(1,len==string::npos ? string::npos : len-1);
459 for(
auto &
i : leaves ) {
460 if (
i->address() ) {
462 ref.
entry =
i->address()->ipar()[1];
463 refs.
refs.push_back(ref);
466 for(
int i = 0,
n=pLinks->
size();
i <
n; ++
i) {
469 refs.
links.push_back(link_id);
471 pair<int,unsigned long> ret =
473 if ( ret.first > 1 ) {
476 << ret.first <<
" " << hex << ret.second << dec <<
endmsg;
490 const string* par = pA->
par();
491 unsigned long* ipar =
const_cast<unsigned long*
>(pA->
ipar());
494 ipar[0] = (
unsigned long)con;
496 size_t len = par[1].find(
'/',1);
497 string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
499 int nb = con->
loadObj(section,par[1],ipar[1],pObj);
500 if ( nb > 1 || (nb == 1 && pObj->
clID() == CLID_DataObject) ) {
506 string tag = par[0]+
":"+par[1];
509 return error(
"createObj> Cannot access the object:"+tag);
519 const unsigned long* ipar = pA->
ipar();
523 const string* par = pA->
par();
524 size_t len = par[1].find(
'/',1);
525 string section = par[1].substr(1,len==string::npos ? string::npos : len-1);
526 int nb = con->
loadRefs(section,par[1],ipar[1],refs);
529 unsigned long nipar[2];
535 for(
size_t j=0,
n=refs.
refs.size(); j<
n; ++j) {
547 <<
"#" << npar[2] <<
"[" << r.
entry <<
"]" <<
endmsg;
548 sc = dataMgr->registerAddress(pA->
registry(),npar[2],nPA);
559 string tag = par[0]+
":"+par[1];
562 return error(
"createObj> Cannot access the object:"+tag+
" [Corrupted file]");
568 return error(
"read> Cannot read object -- no valid object address present ");
void addClient(const IInterface *client)
Add new client to this data source.
bool lookupClient(const IInterface *client) const
Lookup client for this data source.
const std::string & path() const
Access to path of object.
virtual const std::string * par() const =0
Retrieve String parameters.
Definition of the MsgStream class used to transmit messages.
virtual StatusCode update()
Provide empty placeholder for internal object reconfiguration callback.
MsgStream & log() const
Helper: Use message streamer.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
The data converters are responsible to translate data from one representation into another...
std::pair< int, unsigned long > save(const std::string §ion, 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 std::string & fid() const
Access file id.
std::string m_currSection
Property: ROOT section name.
virtual IConverter * createConverter(long typ, const CLID &wanted, const ICnvFactory *fac)
ConversionSvc overload: Create new Converter using factory.
virtual void loadConverter(DataObject *pObj)
ConversionSvc overload: Load the class (dictionary) for the converter.
virtual StatusCode createNullRef(const std::string &path)
Insert null marker for not existent transient object.
IoType
I/O Connection types.
MSG::Level level()
Retrieve output level.
virtual StatusCode createAddress(long svc_type, const CLID &clid, const std::string *par, const unsigned long *ip, IOpaqueAddress *&refpAddress)
IAddressCreator implementation: Address creation.
const std::string & getDb(int which) const
Access database/file name from saved index.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
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.
int m_basketSize
Property: Basket optimization parameter for ROOT TTree (total basket size)
Gaudi::RootDataConnection * m_current
On writing: reference to active output stream.
std::unique_ptr< MsgStream > m_log
Message streamer.
bool isSuccess() const
Test for a status code of SUCCESS.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
int loadObj(const std::string §ion, const std::string &cnt, unsigned long entry, DataObject *&pObj)
Load object.
std::set< std::string > m_badFiles
Set with bad files/tables.
std::vector< Connection * > Connections
void release()
Decrease reference count.
size_t removeClient(const IInterface *client)
Remove client from this data source.
const long ROOT_StorageType
bool patchStreamers(MsgStream &log)
const std::string & getLink(int which) const
Access link name from saved index.
long addLink(const std::string &path, const DataObject *pObject) const
Add link by object reference and path.
void setMessageSvc(MsgStream *m)
Set message service reference.
const std::string FailInputFile
could not open or read from this file
SmartIF< Gaudi::IIODataManager > m_ioMgr
Reference to the I/O data manager.
virtual StatusCode disconnect(const std::string &dbName)
Disconnect from an existing data stream.
const std::string & pfn() const
Access physical file name.
std::vector< int > links
The links of the link manager.
IRegistry * registry() const
Get pointer to Registry.
int loadRefs(const std::string §ion, 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...
LinkManager * linkMgr() const
Retrieve Link manager.
virtual StatusCode commitOutput(const std::string &outputFile, bool do_commit)
Commit pending output.
std::string loadSection
RootCnvSvc Property: Root data cache size.
TYPE * get() const
Get interface pointer.
int dbase
Data members to define object location in the persistent world.
Persistent reference object.
int m_splitLevel
Property: Split level optimization parameter for ROOT TTree.
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.
virtual StatusCode finalize()
stop the service.
StatusCode error(const std::string &msg)
Standard way to print errors.
virtual IRegistry * registry() const =0
Update branch name.
General service interface definition.
TClass * m_classDO
TClass pointer to DataObject class.
This class is used for returning status codes from appropriate routines.
TBranch * getBranch(const std::string §ion, 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.
Link * link(long id)
Retrieve symbolic link identified by ID.
Statistics file converter class definition.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
virtual StatusCode i__createObj(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create transient object from persistent data.
const std::string & getCont(int which) const
Access container name from saved index.
virtual StatusCode finalize()
ConversionSvc overload: Finalize Db service.
NTuple converter class definition for NTuples writted/read using ROOT.
std::pair< int, unsigned long > saveObj(const std::string §ion, 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.
unsigned int CLID
Class ID definition.
bool m_incidentEnabled
Property: Flag to enable incidents on FILE_OPEN.
const StringVec & mergeFIDs() const
Access merged FIDs.
StatusCode connectDatabase(const std::string &dataset, int mode, RootDataConnection **con)
Connect the output file to the service with open mode.
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.
virtual StatusCode connectOutput(const std::string &outputFile, const std::string &openMode)
Connect the output file to the service with open mode.
TClass * m_classRefs
TClass pointer to reference class.
ABC describing basic data connection.
virtual StatusCode connectRead()
Open data stream in read mode.
void resetAge()
Reset age.
RootConnectionSetup * m_setup
Setup structure (ref-counted) and passed to data connections.
Base class for all Incidents (computing events).
std::string m_compression
Property: Compression-algorithm:compression-level.
virtual StatusCode i__fillRepRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the converted object.
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.
virtual StatusCode i__fillObjRefs(IOpaqueAddress *pAddr, DataObject *pObj)
Resolve the references of the created transient object.
virtual IDataProviderSvc * dataSvc() const =0
Retrieve pointer to Transient Store.
virtual SmartIF< IAddressCreator > & addressCreator() const
Retrieve address creator facility.
virtual StatusCode initialize()
Initialize the service.
virtual const id_type & identifier() const =0
Full identifier (or key)
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
virtual StatusCode initialize()
ConversionSvc overload: initialize Db service.
SmartIF< IIncidentSvc > m_incidentSvc
Reference to incident service.
int makeLink(const std::string &p)
Convert path string to path index.
const std::string FailOutputFile
could not create or write to this file
Embedded class defining a symbolic link Note: No copy constructor; bitwise copy (done by the compiler...
Opaque address interface definition.
Base class for all conversion services.
std::string m_ioPerfStats
Property: Enable TTree IOperfStats if not empty; otherwise perf stat file name.
void setIncidentSvc(IIncidentSvc *m)
Set incident service reference.
A DataObject is the base class of any identifiable object on any data store.
Concrete implementation of the IDataConnection interface to access ROOT files.
std::vector< RootRef > refs
The references corresponding to the next layer of items in the data store.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
A LinkManager is the object aggregated into a DataObject, which is responsible for the handling of no...
Helper functions to set/get the application return code.
virtual StatusCode i__createRep(DataObject *pObj, IOpaqueAddress *&refpAddr)
Convert the transient object to the requested persistent representation.
Description: Definition of the ROOT data converter.
int m_bufferSize
Property: Buffer size optimization parameter for ROOT TTree.
long size() const
Retrieve number of link present.
int m_autoFlush
Property: AutoFlush parameter for ROOT TTree (Number of events between auto flushes) ...
TClass * getClass(DataObject *pObject)
Helper: Get TClass for a given DataObject pointer.