1 #define ROOTHISTCNV_RCWNTUPLECNV_CPP 29 return sizeof( T ) * src.
length();
37 return sizeof( T ) * target.
length();
40 template <
typename POD>
41 decltype(
auto ) downcast_item(
const INTupleItem& i )
45 template <
typename POD>
50 template <
typename POD,
typename T>
51 void downcast_item( T&& ) =
delete;
53 template <
typename Item,
typename F>
54 decltype(
auto ) visit( Item& i, F&& f )
58 return f( downcast_item<int>( i ) );
60 return f( downcast_item<char>( i ) );
62 return f( downcast_item<short>( i ) );
64 return f( downcast_item<long>( i ) );
66 return f( downcast_item<long long>( i ) );
68 return f( downcast_item<unsigned char>( i ) );
70 return f( downcast_item<unsigned short>( i ) );
72 return f( downcast_item<unsigned int>( i ) );
74 return f( downcast_item<unsigned long>( i ) );
76 return f( downcast_item<unsigned long long>( i ) );
78 return f( downcast_item<double>( i ) );
80 return f( downcast_item<float>( i ) );
82 return f( downcast_item<bool>( i ) );
97 long item_size =
sizeof( T );
98 long dimension = it->
length();
99 long ndim = it->
ndim() - 1;
107 if ( ind_blk != block_name ) {
108 std::cerr <<
"ERROR: Index for CWNT variable " << ind_var <<
" is in a different block: " << ind_blk
112 }
else if ( it->
dim( ndim ) > 1 ) {
116 for (
int i = ndim - 1; i >= 0; i-- ) {
125 lowerRange = it->
range().lower();
126 upperRange = it->
range().upper();
132 size += item_size * dimension;
142 log <<
MSG::VERBOSE <<
"created tree id: " << rtree->GetName() <<
" title: " << nt->
title() <<
" desc: " << desc
148 long lowerRange, upperRange;
150 long cursize, oldsize = 0;
157 for (
const auto& i : nt->
items() ) {
160 visit( *i, [&](
const auto& data ) {
161 analyzeItem( this->
rootVarType( data.type() ), &data, item, block_name, var_name, lowerRange, upperRange, size );
165 cursize = size - oldsize;
167 log <<
MSG::VERBOSE <<
"item: " << item <<
" type " << i->type() <<
" blk: " << block_name <<
" var: " << var_name
168 <<
" rng: " << lowerRange <<
" " << upperRange <<
" sz: " << size <<
" " << cursize
169 <<
" buf_pos: " << size - cursize <<
endmsg;
172 item_buf_pos.
push_back( size - cursize );
175 item_range_lower.
push_back( lowerRange );
176 item_range_upper.
push_back( upperRange );
182 char* buff = nt->
setBuffer(
new char[size] );
184 log <<
MSG::VERBOSE <<
"Created buffer size: " << size <<
" at " << (
void*)buff << endmsg;
189 char* buf_pos = buff;
194 unsigned int i_item = 0;
195 for (
auto itr = item_name.
cbegin(); itr !=
end; ++itr, ++i_item ) {
197 buf_pos = buff + item_buf_pos[i_item];
206 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 15, 0 ) 207 auto br =
new TBranch( rtree,
209 TBranch* br =
new TBranch(
211 item_fullname[i_item].c_str(), buf_pos, itr->second.c_str() );
213 if ( itr->first !=
"AUTO_BLK" ) {
215 tit = itr->first +
"::" + br->GetTitle();
216 br->SetTitle( tit.
c_str() );
219 log <<
MSG::DEBUG <<
"adding TBranch " << br->GetTitle() <<
" at " << (
void*)buf_pos << endmsg;
222 if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
226 TLeafI* index =
nullptr;
227 TObject* tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
228 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
229 index =
dynamic_cast<TLeafI*
>( tobj );
232 index->SetMaximum( item_range_upper[i_item] );
236 log <<
MSG::ERROR <<
"Could dynamic cast to TLeafI: " << item_fullname[i_item] <<
endmsg;
241 rtree->GetListOfBranches()->Add( br );
257 const auto& items = nt->
items();
259 return dest + visit( *i, [dest](
const auto& item ) {
return saveItem( dest, item ); } );
271 if ( ievt >= rtree->GetEntries() ) {
273 log <<
MSG::ERROR <<
"no more entries in tree to read. max: " << rtree->GetEntries() <<
" current: " << ievt
278 rtree->GetEvent( ievt );
282 auto& items = ntup->
items();
285 return src + visit( *i, [src](
auto& item ) {
return loadItem( src, item ); } );
309 std::string itemName, indexName, item_type, itemTitle, blockName;
311 long size, totsize = 0;
318 TObjArray* lbr = tree->GetListOfBranches();
320 while ( TObject* tobjb = bitr() ) {
322 TBranch* br = (TBranch*)tobjb;
323 itemTitle = br->GetTitle();
325 int ipos = itemTitle.
find(
"::" );
327 blockName = itemTitle.
substr( 0, ipos );
332 TObjArray* lf = br->GetListOfLeaves();
335 while ( TObject* tobj = litr() ) {
337 bool hasRange =
false;
343 TLeaf* tl =
dynamic_cast<TLeaf*
>( tobj );
344 itemName = tl->GetName();
350 if ( blockName !=
"" ) {
351 log <<
MSG::DEBUG <<
"loading NTuple item " << blockName <<
"/" << itemName;
353 log <<
MSG::DEBUG <<
"loading NTuple item " << itemName;
357 TLeaf* indexLeaf = tl->GetLeafCounter( arraySize );
359 if ( arraySize == 0 ) {
360 log <<
MSG::ERROR <<
"TLeaf counter size = 0. This should not happen!" <<
endmsg;
366 indexName = indexLeaf->GetName();
368 indexRange = indexLeaf->GetMaximum();
369 itemSize = indexRange * tl->GetLenType() * arraySize;
371 log <<
"[" << indexName;
374 if ( arraySize != 1 ) {
375 log <<
"][" << arraySize;
380 itemSize = tl->GetLenType() * arraySize;
384 if ( arraySize == 1 ) {
388 log <<
"[" << arraySize <<
"]";
400 hasRange = tl->IsRange();
405 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
407 TLeafI* tli =
dynamic_cast<TLeafI*
>( tobj );
408 if ( tli->IsUnsigned() ) {
409 unsigned long min = 0, max = 0;
411 min = tli->GetMinimum();
412 max = tli->GetMaximum();
415 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
417 long min = 0, max = 0;
419 min = tli->GetMinimum();
420 max = tli->GetMaximum();
423 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
427 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafF" ) ) {
428 float min = 0., max = 0.;
430 TLeafF* tlf =
dynamic_cast<TLeafF*
>( tobj );
432 min = float( tlf->GetMinimum() );
433 max = float( tlf->GetMaximum() );
436 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
439 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafD" ) ) {
440 double min = 0., max = 0.;
442 TLeafD* tld =
dynamic_cast<TLeafD*
>( tobj );
444 min = tld->GetMinimum();
445 max = tld->GetMaximum();
448 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup );
457 log <<
MSG::ERROR <<
"Unable to create ntuple item \"" << itemName <<
"\"" <<
endmsg;
463 log <<
MSG::DEBUG <<
"Total buffer size of NTuple: " << totsize <<
" Bytes." <<
endmsg;
465 char* buf = ntup->
setBuffer(
new char[totsize] );
469 for (
const auto& iitr : itemList ) {
470 TLeaf* leaf = iitr.first;
471 int isize = iitr.second;
473 log <<
MSG::VERBOSE <<
"setting TBranch " << leaf->GetBranch()->GetName() <<
" buffer at " << (
void*)bufpos
476 leaf->GetBranch()->SetAddress( (
void*)bufpos );
494 if ( totsize != ts ) {
495 log <<
MSG::ERROR <<
"buffer size mismatch: " << ts <<
" " << totsize <<
endmsg;
std::string getDirectory()
virtual const std::string & name() const =0
Access _Item name.
constexpr static const auto FAILURE
Definition of the MsgStream class used to transmit messages.
virtual const ItemRange & range() const =0
Access the range if specified.
bool parseName(const std::string &full, std::string &blk, std::string &var)
virtual StatusCode add(INTupleItem *item)=0
Add an item row to the N tuple.
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
#define DECLARE_CONVERTER(x)
Converter of Column-wise NTuple into ROOT format.
StatusCode book(const std::string &desc, INTuple *pObject, TTree *&tree) override
Book the N tuple.
constexpr auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size())
NTuple interface class definition.
virtual void reset()=0
Reset all entries to their default values.
virtual long ndim() const =0
Dimension.
NTuple interface class definition.
virtual long length() const =0
Access the buffer length.
virtual const char * buffer() const =0
Access data buffer (CONST)
virtual StatusCode create(const CLID &typ, const std::string &title, NTuple::Tuple *&refpTuple)=0
Create requested N tuple (Hide constructor)
This class is used for returning status codes from appropriate routines.
StatusCode load(TTree *tree, INTuple *&refpObject) override
Create the transient representation of an object.
Abstract class describing basic data in an Ntuple.
constexpr static const auto SUCCESS
Abstract base class which allows the user to interact with the actual N tuple implementation.
StatusCode readData(TTree *rtree, INTuple *pObject, long ievt) override
Read N tuple data.
virtual const void * buffer() const =0
Access data buffer (CONST)
virtual char * setBuffer(char *buff)=0
Attach data buffer.
virtual const std::string & index() const =0
Access the index _Item.
virtual long dim(long i) const =0
Access individual dimensions.
INTupleItem * createNTupleItem(std::string itemName, std::string blockName, std::string indexName, int indexRange, int arraySize, TYP min, TYP max, INTuple *ntup)
Add an item of a given type to the N tuple.
virtual ItemContainer & items()=0
Access item container.
AttribStringParser::Iterator begin(const AttribStringParser &parser)
virtual bool hasIndex() const =0
Is the tuple have an index item?
SmartIF< INTupleSvc > m_ntupleSvc
Reference to N tuple service.
virtual const std::string & title() const =0
Object title.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
virtual std::string rootVarType(int)
Return ROOT type info:
StatusCode writeData(TTree *rtree, INTuple *pObject) override
Write N tuple data.