19#define ALLOW_ALL_TYPES
43#define S_OK StatusCode::SUCCESS
44#define S_FAIL StatusCode::FAILURE
49static inline istream& loadLong( istream& is ) {
58{
return loadLong(is); }
60{
return loadLong(is); }
61static inline istream&
operator>>(istream& is,
string& )
62{
return loadLong(is); }
66static StatusCode createItem( TTree* tree,
INTuple* tuple, istream& is,
const string& name,
bool add,
69 long len, ndim, dim[4], hasIdx, idxLow, idxLen;
70 long dim1 = 1, dim2 = 1;
73 is >> len >>
c >> ndim >>
c >> hasIdx >>
c;
74 if ( hasIdx ) { getline( is, idxName,
';' ) >> idxLow >>
c >> idxLen >>
c; }
75 for (
int i = 0; i < ndim; i++ ) is >> dim[i] >>
c;
77 TYP low = null, high = null;
78 is >> low >>
c >> high >>
c;
85 dim1 = ( hasIdx ) ? idxLen : dim[0];
89 dim1 = ( hasIdx ) ? idxLen : dim[0];
90 dim2 = ( hasIdx ) ? dim[0] : dim[1];
97 TBranch* b = tree->GetBranch( it->
name().c_str() );
99 b->SetAddress(
const_cast<void*
>( it->
buffer() ) );
102 return tuple->add( it );
105 return tuple->add( it );
114static inline string _tr(
string s ) {
115 string local = std::move( s );
116 auto p = std::begin( local );
117 if ( local.compare( 0, 7,
"<local>" ) == 0 ) p += 7;
119 p, std::end( local ), [](
const char& c ) {
return !isalnum( c ); },
'_' );
129 string path =
fileName( pRegistry );
131 string* par =
const_cast<string*
>( pAddr->
par() );
134 string par_val, par_guid;
135 TBranch* b = con->
getBranch(
"##Descriptors",
"GaudiStatisticsDescription" );
139 b->SetAddress( &ptr );
140 for ( Long64_t i = 0, nent = b->GetEntries(); i < nent; ++i ) {
141 int nb = b->GetEntry( i );
150 par[2] = _tr( cntName );
152 if (
nullptr == tree ) {
return makeError(
"Failed to access N-Tuple tree:" + cntName ); }
153 if ( !par_val.empty() ) {
161 istringstream is( par_val );
162 getline( is, title,
';' ) >> clid >> c >> siz >> c;
163 status = ntupleSvc->create( clid, title, nt );
164 for (
int j = 0; j < siz && status.
isSuccess(); j++ ) {
166 getline( is, title,
';' ) >> typ >> c;
169 status = createItem( tree, nt, is, title,
true, (
unsigned char)0 );
172 status = createItem( tree, nt, is, title,
true, (
unsigned short)0 );
175 status = createItem( tree, nt, is, title,
true, 0u );
178 status = createItem( tree, nt, is, title,
true, 0ul );
181 status = createItem( tree, nt, is, title,
true,
char( 0 ) );
184 status = createItem( tree, nt, is, title,
true,
short( 0 ) );
187 status = createItem( tree, nt, is, title,
true, 0 );
190 status = createItem( tree, nt, is, title,
true, 0l );
193 status = createItem( tree, nt, is, title,
true,
false );
196 status = createItem( tree, nt, is, title,
true, 0.f );
199 status = createItem( tree, nt, is, title,
true, 0. );
214 status = createItem( tree, nt, is, title,
false,
static_cast<IOpaqueAddress*
>(
nullptr ) );
217 status = createItem( tree, nt, is, title,
true,
static_cast<void*
>(
nullptr ) );
226 return makeError(
"createObj[NTuple]> Cannot determine column!" );
230 unsigned long* ipar =
const_cast<unsigned long*
>( rpA->
ipar() );
231 log() <<
MSG::DEBUG <<
"Created N-tuple with description:" << par_val << endl;
232 ipar[0] =
reinterpret_cast<uintptr_t
>( con );
237 refpObject =
nullptr;
250 if ( !tupl || !rpA )
return makeError(
"updateObj> Invalid Tuple reference." );
252 if ( !con )
return makeError(
"updateObj> Failed to access data source!" );
254 if ( !tree )
return makeError(
"Failed to access data tree:" + pAddr->
par()[1] );
257#ifdef __POOL_COMPATIBILITY
259 return i__updateObjPool( rpA, tupl, tree, con );
261 return makeError(
"Failed to access reference branch for data tree:" + rpA->
par()[1] );
268 const string* par = rpA->
par();
269 unsigned long* ipar =
const_cast<unsigned long*
>( rpA->
ipar() );
271 if ( Long64_t( ipar[1] ) <= tree->GetEntries() ) {
273 Cont& it = tupl->
items();
274 size_t k, n = it.size();
275 vector<RootRef*> paddr( n );
276 vector<RootRef> addr( n );
277 for ( k = 0; k < n; ++k ) {
278 Cont::value_type j = it[k];
279 switch ( j->type() ) {
282 tree->SetBranchAddress( j->name().c_str(), &paddr[k] );
289 ULong64_t last = tree->GetEntries();
293 if ( !( criteria.length() == 0 || criteria ==
"*" ) ) {
294 if ( rpA->
select ==
nullptr ) {
296 rpA->
select =
new TTreeFormula( tree->GetName(), criteria.c_str(), tree );
298 rpA->
select->SetTree( tree );
299 for ( ; ipar[1] < last; ++ipar[1] ) {
300 tree->LoadTree( ipar[1] );
302 if ( fabs( rpA->
select->EvalInstance( 0 ) ) > std::numeric_limits<double>::epsilon() ) {
break; }
307 if ( ipar[1] < last ) {
308 unsigned long entry = ipar[1];
309 if ( tree->GetEntry( entry ) > 1 ) {
311 string* spar =
nullptr;
312 for ( k = 0; k < n; ++k ) {
313 Cont::value_type j = it[k];
314 switch ( j->type() ) {
319 spar = (
string*)pA->
par();
320 ipar = (
unsigned long*)pA->
ipar();
322 pair<const RootRef*, const RootDataConnection::ContainerSection*> ls =
325 if ( ls.first->dbase >= 0 ) {
329 r->
dbase += ls.first->dbase;
331 r->
link += ls.first->link;
333 if (
log().isActive() ) {
334 log() <<
"Refs: LS [" << entry <<
"] -> " << ls.first->dbase <<
"," << ls.first->container <<
","
335 << ls.first->link <<
"," << ls.first->entry <<
" DB:" << con->
getDb( r->
dbase ) <<
endmsg;
369 if ( pAddr )
return S_OK;
372 string path =
fileName( pRegistry );
374 string secName = cntName;
377 if ( !status.
isSuccess() ) {
return makeError(
"Failed to access Tuple file:" + path ); }
378 TTree* tree = con->
getSection( _tr( secName ),
true );
379 if (
nullptr != nt ) {
384 os << nt->
title() <<
';' << pObj->
clID() <<
';' << items.size() <<
';';
385 map<string, TBranch*> branches;
386 TBranch* b =
nullptr;
387 for ( item_no = 0; item_no < items.size(); ++item_no ) {
391 const string& n = itm->
name();
392 switch ( itm->
type() ) {
395 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
399 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
403 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
407 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
411 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
415 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
419 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
423 b = tree->Branch( n.c_str(),
const_cast<void*
>( itm->
buffer() ), desc.c_str() );
426 return makeError(
"Column " + it->
index() +
" is not a valid index column!" );
431 for ( item_no = 0; item_no < items.size(); ++item_no ) {
433 const string& n = it->
name();
434 os <<
'{' << n <<
';' << it->
type() <<
';' << it->
length() <<
';' << it->
ndim() <<
';' << it->
hasIndex() <<
';';
436 os << it->
index() <<
';';
438 switch ( itm->
type() ) {
465 " is not a valid index column!" );
468 for (
long k = 0; k < it->
ndim(); k++ ) { os << it->
dim( k ) <<
';'; }
470 TClass* cl =
nullptr;
471 switch ( it->
type() ) {
474 os << 0 <<
';' << 0 <<
';';
478 os << 0 <<
';' << 0 <<
';';
481 if ( it->
length() == 1 ) {
483 os << 0 <<
';' << 0 <<
';';
484 cl = TClass::GetClass( desc.c_str(), kTRUE );
488 if ( it->
length() == 1 ) {
489 os << 0 <<
';' << 0 <<
';';
490 cl = TClass::GetClass( it->
typeID(), kTRUE );
542 if ( branches.find( n ) == branches.end() ) {
545 switch ( it->
ndim() ) {
550 sprintf( text,
"[%ld]", it->
dim( 0 ) );
556 desc = n + tmp +
"[" + itm->
name() +
"]" + desc;
558 sprintf( text,
"[%ld]", it->
dim( 0 ) );
559 desc = n + tmp + text + desc;
563 switch ( it->
type() ) {
565 branches[n] = tree->Branch( n.c_str(), cl->GetName(),
const_cast<void*
>( it->
buffer() ) );
568 branches[n] = tree->Branch( n.c_str(), cl->GetName(),
const_cast<void*
>( it->
buffer() ) );
571 branches[n] = tree->Branch( n.c_str(),
const_cast<void*
>( it->
buffer() ), desc.c_str() );
580 status =
m_dbMgr->commitOutput( path,
true );
582 string spar[] = { path, cntName };
583 unsigned long ipar[] = { (
unsigned long)con, ~0x0u };
588 ( (
unsigned long*)rpA->
ipar() )[0] = (
unsigned long)con;
612 if ( tupl && pReg && rpA ) {
614 unsigned long* ipar =
const_cast<unsigned long*
>( pAddr->
ipar() );
619 Cont& it = tupl->
items();
620 size_t k, n = it.size();
621 vector<RootRef*> paddr( n );
622 vector<RootRef> addr( n );
623 for ( k = 0; k < n; ++k ) {
625 Cont::value_type j = it[k];
626 switch ( j->type() ) {
633 addr[k].entry = pA->
ipar()[1];
635 tree->SetBranchAddress( j->name().c_str(), &paddr[k] );
641 int nb = tree->Fill();
642 if ( nb > 1 ) ++ipar[1];
643 for ( k = 0; k < n; ++k ) it[k]->reset();
646 return makeError(
"fillRepRefs> Failed to access data tree:" + cntName );
648 return makeError(
"fillRepRefs> Failed to access data source!" );
650 return makeError(
"fillRepRefs> Invalid Tuple reference." );
653#ifdef __POOL_COMPATIBILITY
663 IOBuffer() =
default;
664 virtual ~IOBuffer() {
679static inline int load(
int blob, IOBuffer& s,
void* buff ) {
683 s.swapFromBuffer( buff, len *
sizeof( T ) );
690inline int load<string>(
int blob, IOBuffer& s,
void* ptr ) {
692 string* str = (
string*)ptr;
701 const string*
par = rpA->
par();
702 unsigned long* ipar =
const_cast<unsigned long*
>( rpA->
ipar() );
704 if ( Long64_t( ipar[1] ) <= tree->GetEntries() ) {
705 Cont& it = tupl->
items();
706 size_t k,
n = it.size();
707 vector<PoolDbTokenWrap*> paddr( n );
708 vector<PoolDbTokenWrap> addr( n );
709 vector<int> blob_items( n, 0 );
710 for ( k = 0; k <
n; ++k ) {
711 Cont::value_type j = it[k];
712 switch ( j->type() ) {
715 tree->SetBranchAddress( j->name().c_str(), &paddr[k] );
718 if (
nullptr == tree->GetBranch( j->name().c_str() ) ) blob_items[k] = 1;
722 ULong64_t last = (ULong64_t)tree->GetEntries();
726 if ( !( criteria.length() == 0 || criteria ==
"*" ) ) {
727 if ( rpA->
select ==
nullptr ) {
729 rpA->
select =
new TTreeFormula( tree->GetName(), criteria.c_str(), tree );
731 rpA->
select->SetTree( tree );
733 for ( ; ipar[1] < last; ++ipar[1] ) {
734 tree->LoadTree( ipar[1] );
736 if ( fabs( rpA->
select->EvalInstance( 0 ) ) > std::numeric_limits<double>::epsilon() ) {
break; }
741 if ( ipar[1] < last ) {
743 UCharDbArray* pblob = &blob.d;
744 tree->GetBranch(
"BlobData" )->SetAddress( &pblob );
745 if ( tree->GetEntry( ipar[1] ) > 1 ) {
748 for ( k = 0; k <
n; ++k ) {
749 Cont::value_type j = it[k];
750 char* buf = (
char*)j->buffer();
751 switch ( j->type() ) {
753 RootRef r = con->
tool()->
poolRef( addr[k].token.m_oid.first );
754 GenericAddress* pA = ( *(GenericAddress**)buf );
756 string* spar = (
string*)pA->
par();
757 ipar = (
unsigned long*)pA->
ipar();
762 ipar[1] = addr[k].token.m_oid.second;
775 sc = load<unsigned char>( blob_items[k], blob, buf );
778 sc = load<unsigned short>( blob_items[k], blob, buf );
781 sc = load<unsigned int>( blob_items[k], blob, buf );
784 sc = load<unsigned long>( blob_items[k], blob, buf );
787 sc = load<char>( blob_items[k], blob, buf );
790 sc = load<short>( blob_items[k], blob, buf );
793 sc = load<int>( blob_items[k], blob, buf );
796 sc = load<long>( blob_items[k], blob, buf );
799 sc = load<bool>( blob_items[k], blob, buf );
802 sc = load<float>( blob_items[k], blob, buf );
805 sc = load<double>( blob_items[k], blob, buf );
808 sc = load<string>( blob_items[k], blob, buf );
811 sc = load<char*>( blob_items[k], blob, buf );
825 log() <<
"CANNOT Set Ntuple token: dynamic_cast<GenericAddress*> is NULL";
828 log() <<
"CANNOT Set Ntuple token: invalid address buffer";
const long POOL_ROOTKEY_StorageType
unsigned int CLID
Class ID definition.
const long POOL_ROOT_StorageType
const long POOL_ROOTTREE_StorageType
const long ROOT_StorageType
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
StreamBuffer & operator>>(StreamBuffer &s, std::vector< T > &v)
SmartIF< IDataProviderSvc > & dataProvider() const override
Get Data provider service.
A DataObject is the base class of any identifiable object on any data store.
IRegistry * registry() const
Get pointer to Registry.
virtual const CLID & clID() const
Retrieve reference to class definition structure.
virtual unsigned long release()
release reference to object
void resetAge()
Reset age.
TTreeFormula * select
Pointer to ROOT select statement (filled for N-tuples only)
TTree * section
Pointer to ROOT TTree (filled for N-tuples only)
RootCnvSvc * m_dbMgr
Conversion service needed for proper operation to forward requests.
long repSvcType() const override
Retrieve the class type of the data store the converter uses.
Concrete implementation of the IDataConnection interface to access ROOT files.
const std::string & getLink(int which) const
Access link name from saved index.
Tool * tool() const
Access tool.
TTree * getSection(std::string_view sect, bool create=false)
Access TTree section from section name. The section is created if required.
TBranch * getBranch(std::string_view section, std::string_view branch_name)
Access data branch by name: Get existing branch in read only mode.
void makeRef(const IRegistry &pA, RootRef &ref)
Create reference object from registry entry.
const std::string & getDb(int which) const
Access database/file name from saved index.
std::pair< const RootRef *, const ContainerSection * > getMergeSection(std::string_view container, int entry) const
Access link section for single container and entry.
const std::string & getCont(int which) const
Access container name from saved index.
StatusCode fillRepRefs(IOpaqueAddress *pAdd, DataObject *pObj) override
Resolve the references of the converted object.
StatusCode i__updateObjRoot(RootAddress *rpA, INTuple *tupl, TTree *tree, RootDataConnection *con)
Update the transient object: NTuples end here when reading records.
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAdd) override
Converter overrides: Convert the transient object to the requested representation.
StatusCode createObj(IOpaqueAddress *pAddress, DataObject *&refpObject) override
Converter overrides: Update the references of an updated transient object.
StatusCode updateObj(IOpaqueAddress *pAddress, DataObject *pObject) override
Update the transient object: NTuples end here when reading records.
StatusCode saveDescription(const std::string &path, const std::string &ident, const std::string &desc, const std::string &opt, const CLID &clid)
Save statistics object description.
virtual const std::string fileName(IRegistry *pReg) const
Retrieve the name of the file a given object is placed into.
StatusCode makeError(const std::string &msg, bool throw_exception=false) const
Helper method to issue error messages.
MsgStream & log() const
Helper to use mesage logger.
virtual const std::string containerName(IRegistry *pDir) const
Retrieve the name of the container a given object is placed into.
Generic Transient Address.
void setClID(const CLID &clid)
Access : Set class ID of the link.
const std::string * par() const override
Retrieve string parameters.
const unsigned long * ipar() const override
Retrieve integer parameters.
void setSvcType(long typ)
Access : set the storage type of the class id.
NTuple interface class definition.
std::vector< INTupleItem * > ItemContainer
virtual ISelectStatement * selector()=0
Access selector.
virtual ItemContainer & items()=0
Access item container.
virtual const std::string & title() const =0
Object title.
NTuple interface class definition.
virtual long ndim() const =0
Dimension.
virtual const void * buffer() const =0
Access data buffer (CONST)
virtual long dim(long i) const =0
Access individual dimensions.
virtual const std::string & index() const =0
Access the index _Item.
virtual const std::type_info & typeID() const =0
Compiler type ID.
virtual long type() const =0
Type information of the item.
virtual long length() const =0
Access the buffer length.
virtual INTupleItem * indexItem()=0
Pointer to index column (if present, 0 else)
virtual const std::string & name() const =0
Access _Item name.
virtual bool hasIndex() const =0
Is the tuple have an index item?
Opaque address interface definition.
virtual unsigned long release()=0
release reference to object
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const std::string * par() const =0
Retrieve String parameters.
virtual IRegistry * registry() const =0
Update branch name.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
virtual const name_type & name() const =0
Name of the directory (or key)
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
A select statement can either contain.
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.
Abstract class describing basic data in an Ntuple.
virtual const ItemRange & range() const =0
Access the range if specified.
static _Item * create(INTuple *tup, const std::string &name, const std::type_info &info, TYP min, TYP max, TYP def)
Create instance.
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.
TYP lower() const
Lower boundary of range.
TYP upper() const
Upper boundary of range.
Abstract base class which allows the user to interact with the actual N tuple implementation.
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Kernel objects: SmartRef.
This class is used for returning status codes from appropriate routines.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
The stream buffer is a small object collecting object data.
This file provides a Grammar for the type Gaudi::Accumulators::Axis It allows to use that type from p...
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
std::string description
Description string.
std::string container
Identifier of description.
Persistent reference object.
int dbase
Data members to define object location in the persistent world.
Shadow class to mimik POOL blobs.
unsigned char * m_buffer
Buffer with object content.
int m_size
Size of buffer.