9 #define ALLOW_ALL_TYPES
11 #include "RootCnv/RootRefs.h"
12 #include "RootCnv/RootAddress.h"
13 #include "RootCnv/RootNTupleCnv.h"
14 #include "RootCnv/RootDataConnection.h"
16 #include "GaudiKernel/NTuple.h"
17 #include "GaudiKernel/SmartIF.h"
18 #include "GaudiKernel/SmartRef.h"
19 #include "GaudiKernel/INTupleSvc.h"
20 #include "GaudiKernel/IRegistry.h"
21 #include "GaudiKernel/ISelectStatement.h"
22 #include "GaudiKernel/ContainedObject.h"
23 #include "GaudiKernel/StreamBuffer.h"
33 #define S_OK StatusCode::SUCCESS
34 #define S_FAIL StatusCode::FAILURE
36 using namespace Gaudi;
39 static inline istream& loadLong(istream& is) {
45 {
return loadLong(is); }
49 {
return loadLong(is); }
51 {
return loadLong(is); }
52 static inline istream&
operator>>(istream& is,
string& )
53 {
return loadLong(is); }
56 template<
class TYP>
static
59 long len, ndim, dim[4], hasIdx, idxLow, idxLen;
60 long dim1 = 1, dim2 = 1;
67 getline(is, idxName,
';') >> idxLow >> c >> idxLen >>
c;
69 for (
int i = 0;
i < ndim;
i++ )
72 TYP low = null, high = null;
73 is >> low >> c >> high >>
c;
81 dim1 = (hasIdx) ? idxLen : dim[0];
92 dim1 = (hasIdx) ? idxLen : dim[0];
93 dim2 = (hasIdx) ? dim[0] : dim[1];
108 TBranch* b = tree->GetBranch(it->
name().c_str());
110 b->SetAddress((
void*)it->
buffer());
114 return tuple->
add(it);
117 return tuple->
add(it);
120 template <
class T>
static inline void putRange(ostream& os,
NTuple::_Data<T>* it) {
125 static inline string _tr(
string s) {
126 string local = std::move(s);
128 if ( local.compare(0,7,
"<local>")==0 ) p+=7;
130 [](
const char& c) {
return !isalnum(c); },
142 string path = fileName(pRegistry);
143 string cntName = containerName(pRegistry);
144 string*
par =
const_cast<string*
>(pAddr->
par());
147 string par_val, par_guid;
148 TBranch* b = con->
getBranch(
"##Descriptors",
"GaudiStatisticsDescription");
153 for(Long64_t
i=0, nent = b->GetEntries();
i<nent; ++
i) {
154 int nb = b->GetEntry(
i);
163 par[2] = _tr(cntName);
165 if (
nullptr == tree ) {
166 return makeError(
"Failed to access N-Tuple tree:"+cntName);
168 if ( !par_val.empty() ) {
169 auto ntupleSvc = dataProvider().as<
INTupleSvc>();
176 istringstream is(par_val);
177 getline(is, title,
';') >> clid >> c >> siz >>
c;
178 status = ntupleSvc->create(clid, title, nt);
179 for (
int j = 0; j < siz && status.
isSuccess(); j++ ) {
181 getline(is, title,
';') >> typ >>
c;
185 status = createItem(tree, nt, is, title,
true, (
unsigned char)0);
188 status = createItem(tree, nt, is, title,
true, (
unsigned short)0);
191 status = createItem(tree, nt, is, title,
true, (
unsigned int)0);
194 status = createItem(tree, nt, is, title,
true, (
unsigned long)0);
197 status = createItem(tree, nt, is, title,
true,
char(0));
200 status = createItem(tree, nt, is, title,
true,
short(0));
203 status = createItem(tree, nt, is, title,
true,
int(0));
206 status = createItem(tree, nt, is, title,
true,
long(0));
209 status = createItem(tree, nt, is, title,
true,
false);
212 status = createItem(tree, nt, is, title,
true,
float(0.0));
215 status = createItem(tree, nt, is, title,
true,
double(0.0));
230 status = createItem(tree, nt, is, title,
false, (
IOpaqueAddress*)
nullptr);
233 status = createItem(tree, nt, is, title,
true, (
void*)
nullptr);
242 <<
"Error connecting (Unknown) column:" << j <<
endmsg
244 return makeError(
"createObj[NTuple]> Cannot determine column!");
248 unsigned long* ipar =
const_cast<unsigned long*
>(rpA->
ipar());
251 ipar[0] = (
unsigned long)con;
257 refpObject =
nullptr;
270 if (
nullptr != tupl &&
nullptr != rpA ) {
277 return i__updateObjRoot(rpA,tupl,tree,con);
278 #ifdef __POOL_COMPATIBILITY
280 return i__updateObjPool(rpA,tupl,tree,con);
282 return makeError(
"Failed to access reference branch for data tree:"+rpA->
par()[1]);
285 return makeError(
"Failed to access data tree:"+pAddr->
par()[1]);
287 return makeError(
"updateObj> Failed to access data source!");
289 return makeError(
"updateObj> Invalid Tuple reference.");
295 const string*
par = rpA->
par();
296 unsigned long* ipar =
const_cast<unsigned long*
>(rpA->
ipar());
298 if ( Long64_t(ipar[1]) <= tree->GetEntries() ) {
300 Cont& it = tupl->
items();
301 size_t k,
n = it.size();
302 vector<RootRef*> paddr(n);
303 vector<RootRef> addr(n);
304 for(k = 0; k <
n; ++k) {
305 Cont::value_type j = it[k];
310 tree->SetBranchAddress(j->name().c_str(),&paddr[k]);
317 ULong64_t last = (ULong64_t)tree->GetEntries();
322 if ( !(criteria.length() == 0 || criteria ==
"*") ) {
323 if ( rpA->
select ==
nullptr ) {
325 rpA->
select =
new TTreeFormula(tree->GetName(),criteria.c_str(), tree);
327 rpA->
select->SetTree(tree);
328 for( ; ipar[1] < last; ++ipar[1]) {
329 tree->LoadTree(ipar[1]);
331 if ( fabs(rpA->
select->EvalInstance(0)) > std::numeric_limits<float>::epsilon() ) {
338 if ( ipar[1] < last ) {
339 unsigned long entry = ipar[1];
340 if ( tree->GetEntry(entry) > 1 ) {
342 string *spar =
nullptr;
343 for(k = 0; k <
n; ++k) {
344 Cont::value_type j = it[k];
351 spar = (
string*)pA->
par();
352 ipar = (
unsigned long*)pA->
ipar();
354 pair<const RootRef*,const RootDataConnection::ContainerSection*> ls = con->
getMergeSection(tree->GetName(),entry);
356 if ( ls.first->dbase >= 0 ) {
360 r->
dbase += ls.first->dbase;
362 r->
link += ls.first->link;
364 if (
log().isActive() ) {
365 log() <<
"Refs: LS [" << entry <<
"] -> "
366 << ls.first->dbase <<
"," << ls.first->container
367 <<
"," << ls.first->link
368 <<
"," << ls.first->entry
402 if (
nullptr != pRegistry ) {
404 if (
nullptr != pAddr ) {
409 string path = fileName(pRegistry);
410 string cntName = containerName(pRegistry);
411 string secName = cntName.c_str();
415 return makeError(
"Failed to access Tuple file:"+path);
417 TTree* tree = con->
getSection(_tr(secName),
true);
418 if (
nullptr != nt ) {
423 os << nt->
title()<<
';'<<pObj->
clID()<<
';'<<items.size()<<
';';
424 map<string,TBranch*> branches;
425 TBranch* b =
nullptr;
426 for(item_no = 0; item_no < items.size(); ++item_no ) {
430 const string&
n = itm->
name();
431 switch( itm->
type() )
435 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
439 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
443 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
447 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
451 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
455 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
459 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
463 b = tree->Branch(n.c_str(),(
void*)itm->
buffer(),desc.c_str());
466 return makeError(
"Column "+it->
index()+
" is not a valid index column!");
471 for(item_no = 0; item_no < items.size(); ++item_no ) {
473 const string&
n = it->
name();
481 os << it->
index() <<
';';
483 switch( itm->
type() )
510 return makeError(
"NTuple:"+pRegistry->
name()+
" Column "+it->
index()+
511 " is not a valid index column!");
514 for (
long k = 0; k < it->
ndim(); k++ ) {
515 os << it->
dim(k) <<
';';
518 TClass* cl =
nullptr;
523 os << 0 <<
';' << 0 <<
';';
527 os << 0 <<
';' << 0 <<
';';
530 if ( it->
length() == 1 ) {
532 os << 0 <<
';' << 0 <<
';';
533 cl = TClass::GetClass(desc.c_str(),kTRUE);
537 if ( it->
length() == 1 ) {
538 os << 0 <<
';' << 0 <<
';';
539 cl = TClass::GetClass(it->
typeID(), kTRUE);
588 return makeError(
"Create item[FAIL]: "+it->
name());
591 if ( branches.find(n) == branches.end() ) {
600 sprintf(text,
"[%ld]",it->
dim(0));
605 desc = n + tmp +
"[" + itm->
name() +
"]" + desc;
608 sprintf(text,
"[%ld]",it->
dim(0));
609 desc = n + tmp + text + desc;
612 log() <<
MSG::DEBUG <<
"Create branch:" << n <<
" Desc:" << desc
617 branches[
n] = tree->Branch(n.c_str(),cl->GetName(),(
void*)it->
buffer());
620 branches[
n] = tree->Branch(n.c_str(),cl->GetName(),(
void*)it->
buffer());
623 branches[
n] = tree->Branch(n.c_str(),(
void*)it->
buffer(),desc.c_str());
631 status = saveDescription(path,cntName,os.str(),
"",pObj->
clID());
633 status = m_dbMgr->commitOutput(path,
true);
635 string spar[] = {
path, cntName};
636 unsigned long ipar[] = { (
unsigned long)con, ~0x0u };
637 status = m_dbMgr->createAddress(repSvcType(),pObj->
clID(),spar,ipar,pAddr);
640 ((
unsigned long*)rpA->
ipar())[0] = (
unsigned long)con;
661 if ( tupl && pReg && rpA ) {
662 string cntName = containerName(pReg);
663 unsigned long* ipar =
const_cast<unsigned long*
>(pAddr->
ipar());
668 Cont& it = tupl->
items();
669 size_t k,
n = it.size();
670 vector<RootRef*> paddr(n);
671 vector<RootRef> addr(n);
672 for(k = 0; k <
n; ++k) {
674 Cont::value_type j = it[k];
683 addr[k].entry = pA->
ipar()[1];
685 tree->SetBranchAddress(j->name().c_str(),&paddr[k]);
691 int nb = tree->Fill();
692 if ( nb>1 ) ++ipar[1];
693 for(k = 0; k <
n; ++k) it[k]->reset();
696 return makeError(
"fillRepRefs> Failed to access data tree:"+cntName);
698 return makeError(
"fillRepRefs> Failed to access data source!");
700 return makeError(
"fillRepRefs> Invalid Tuple reference.");
703 #ifdef __POOL_COMPATIBILITY
704 #include "RootCnv/PoolClasses.h"
713 IOBuffer() =
default;
714 virtual ~IOBuffer() { m_pointer=0; m_length=0; m_buffer=
nullptr;}
720 template <
class T>
static inline int load(
int blob, IOBuffer& s,
void* buff) {
724 s.swapFromBuffer(buff, len*
sizeof(T));
730 template <>
inline int load<string>(
int blob, IOBuffer&
s,
void* ptr) {
732 string* str = (
string*)ptr;
741 const string*
par = rpA->
par();
742 unsigned long* ipar =
const_cast<unsigned long*
>(rpA->
ipar());
744 if ( Long64_t(ipar[1]) <= tree->GetEntries() ) {
745 Cont& it = tupl->
items();
746 size_t k,
n = it.size();
747 vector<PoolDbTokenWrap*> paddr(n);
748 vector<PoolDbTokenWrap> addr(n);
749 vector<int> blob_items(n,0);
750 for(k = 0; k <
n; ++k) {
751 Cont::value_type j = it[k];
756 tree->SetBranchAddress(j->name().c_str(),&paddr[k]);
759 if (
nullptr == tree->GetBranch(j->name().c_str()) ) blob_items[k] = 1;
763 ULong64_t last = (ULong64_t)tree->GetEntries();
768 if ( !(criteria.length() == 0 || criteria ==
"*") ) {
769 if ( rpA->
select ==
nullptr ) {
771 rpA->
select =
new TTreeFormula(tree->GetName(),criteria.c_str(), tree);
773 rpA->
select->SetTree(tree);
775 for( ; ipar[1] < last; ++ipar[1]) {
776 tree->LoadTree(ipar[1]);
778 if ( fabs(rpA->
select->EvalInstance(0)) > std::numeric_limits<float>::epsilon() ) {
785 if ( ipar[1] < last ) {
788 tree->GetBranch(
"BlobData")->SetAddress(&pblob);
789 if ( tree->GetEntry(ipar[1]) > 1 ) {
792 for(k = 0; k <
n; ++k) {
793 Cont::value_type j = it[k];
794 char* buf = (
char*)j->buffer();
801 string *spar = (
string*)pA->
par();
802 ipar = (
unsigned long*)pA->
ipar();
807 ipar[1] = addr[k].token.m_oid.second;
842 log() <<
"CANNOT Set Ntuple token: dynamic_cast<GenericAddress*> is NULL";
845 log() <<
"CANNOT Set Ntuple token: invalid address buffer";
const long POOL_ROOTTREE_StorageType
virtual const std::string * par() const =0
Retrieve String parameters.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
virtual long type() const =0
Type information of the item.
const std::string * par() const override
Retrieve string parameters.
A select statement can either contain.
const std::string & getDb(int which) const
Access database/file name from saved index.
void setSvcType(long typ)
Access : set the storage type of the class id.
TTreeFormula * select
Pointer to ROOT select statement (filled for N-tuples only)
The stream buffer is a small object collecting object data.
bool isSuccess() const
Test for a status code of SUCCESS.
auto begin(reverse_wrapper< T > &w)
int m_size
Size of buffer.
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
virtual StatusCode add(INTupleItem *item)=0
Add an item row to the N tuple.
std::vector< INTupleItem * > ItemContainer
virtual const std::string & title() const =0
Object title.
virtual const name_type & name() const =0
Name of the directory (or key)
virtual const ItemRange & range() const =0
Access the range if specified.
const std::string & getLink(int which) const
Access link name from saved index.
virtual unsigned long release()=0
release reference to object
const long POOL_ROOTKEY_StorageType
Generic Transient Address.
virtual ISelectStatement * selector()=0
Access selector.
virtual const std::type_info & typeID() const =0
Compiler type ID.
virtual bool hasIndex() const =0
Is the tuple have an index item?
unsigned char * m_buffer
Buffer with object content.
IRegistry * registry() const
Get pointer to Registry.
Shadow class to mimik POOL blobs.
static _Array * create(INTuple *tup, const std::string &name, const std::type_info &info, const std::string &index, long len, TYP min, TYP max, TYP def)
Create instance.
virtual const std::string & name() const =0
Access _Item name.
NTuple interface class definition.
int dbase
Data members to define object location in the persistent world.
Persistent reference object.
NTuple interface class definition.
void setClID(const CLID &clid)
Access : Set class ID of the link.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
virtual IRegistry * registry() const =0
Update branch name.
virtual INTupleItem * indexItem()=0
Pointer to index column (if present, 0 else)
auto end(reverse_wrapper< T > &w)
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.
virtual long dim(long i) const =0
Access individual dimensions.
std::string description
Description string.
std::pair< const RootRef *, const ContainerSection * > getMergeSection(const std::string &container, int entry) const
Access link section for single container and entry.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
const std::string & getCont(int which) const
Access container name from saved index.
TYP upper() const
Upper boundary of range.
Abstract class describing basic data in an Ntuple.
virtual const std::string & criteria() const =0
Access the selection string.
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
Tool * tool() const
Access tool.
Abstract base class which allows the user to interact with the actual N tuple implementation.
virtual long type() const =0
Access the type of the object.
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAdd) override
Converter overrides: Convert the transient object to the requested representation.
virtual unsigned long release()
release reference to object
StatusCode fillRepRefs(IOpaqueAddress *pAdd, DataObject *pObj) override
Resolve the references of the converted object.
virtual long ndim() const =0
Dimension.
StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *pObject) override
Update the transient object: NTuples end here when reading records.
void resetAge()
Reset age.
std::string container
Identifier of description.
const unsigned long * ipar() const override
Retrieve integer parameters.
virtual ItemContainer & items()=0
Access item container.
static _Item * create(INTuple *tup, const std::string &name, const std::type_info &info, TYP min, TYP max, TYP def)
Create instance.
TTree * section
Pointer to ROOT TTree (filled for N-tuples only)
Opaque address interface definition.
unsigned int CLID
Class ID definition.
StatusCode i__updateObjRoot(RootAddress *rpA, INTuple *tupl, TTree *tree, RootDataConnection *con)
Update the transient object: NTuples end here when reading records.
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Converter overrides: Update the references of an updated transient object.
A DataObject is the base class of any identifiable object on any data store.
Concrete implementation of the IDataConnection interface to access ROOT files.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
StreamBuffer & operator>>(StreamBuffer &s, std::vector< T > &v)
Helper functions to set/get the application return code.
TYP lower() const
Lower boundary of range.
virtual const std::string & index() const =0
Access the index _Item.
static _Matrix * create(INTuple *tup, const std::string &name, const std::type_info &info, const std::string &index, long ncol, long nrow, TYP min, TYP max, TYP def)
Create instance.
TTree * getSection(const std::string §, bool create=false)
Access TTree section from section name. The section is created if required.
virtual long length() const =0
Access the buffer length.
virtual const void * buffer() const =0
Access data buffer (CONST)
const long ROOT_StorageType
const long POOL_ROOT_StorageType