11 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
22 #include <type_traits>
36 static_assert( std::is_trivially_copyable_v<T>,
"T must be trivally copyable" );
38 return sizeof( T ) * src.length();
43 static_assert( std::is_trivially_copyable_v<T>,
"T must be trivally copyable" );
45 return sizeof( T ) *
target.length();
48 template <
typename POD>
49 decltype(
auto ) downcast_item(
const INTupleItem& i ) {
52 template <
typename POD>
56 template <
typename POD,
typename T>
57 void downcast_item( T&& ) =
delete;
59 template <
typename Item,
typename F>
60 decltype(
auto ) visit(
Item& i, F&& f ) {
63 return f( downcast_item<int>( i ) );
65 return f( downcast_item<char>( i ) );
67 return f( downcast_item<short>( i ) );
69 return f( downcast_item<long>( i ) );
71 return f( downcast_item<long long>( i ) );
73 return f( downcast_item<unsigned char>( i ) );
75 return f( downcast_item<unsigned short>( i ) );
77 return f( downcast_item<unsigned int>( i ) );
79 return f( downcast_item<unsigned long>( i ) );
81 return f( downcast_item<unsigned long long>( i ) );
83 return f( downcast_item<double>( i ) );
85 return f( downcast_item<float>( i ) );
87 return f( downcast_item<bool>( i ) );
102 long item_size =
sizeof( T );
103 long dimension = it->length();
104 long ndim = it->ndim() - 1;
106 if ( it->hasIndex() || it->length() > 1 ) { desc +=
'['; }
107 if ( it->hasIndex() ) {
110 if ( ind_blk != block_name ) {
111 std::cerr <<
"ERROR: Index for CWNT variable " << ind_var <<
" is in a different block: " << ind_blk
115 }
else if ( it->dim( ndim ) > 1 ) {
119 for (
int i = ndim - 1; i >= 0; i-- ) {
123 if ( it->hasIndex() || it->length() > 1 ) { desc +=
']'; }
128 if constexpr ( std::is_integral_v<T> ) {
132 lowerRange = it->
range().lower();
133 upperRange = it->
range().upper();
138 size += item_size * dimension;
148 log <<
MSG::VERBOSE <<
"created tree id: " << rtree->GetName() <<
" title: " << nt->
title() <<
" desc: " << desc
154 long lowerRange, upperRange;
156 long cursize, oldsize = 0;
163 for (
const auto& i : nt->
items() ) {
166 visit( *i, [&](
const auto& data ) {
167 analyzeItem( this->
rootVarType( data.type() ), &data, item, block_name, var_name, lowerRange, upperRange,
size );
171 cursize =
size - oldsize;
173 log <<
MSG::VERBOSE <<
"item: " << item <<
" type " << i->type() <<
" blk: " << block_name <<
" var: " << var_name
174 <<
" rng: " << lowerRange <<
" " << upperRange <<
" sz: " <<
size <<
" " << cursize
181 item_range_lower.
push_back( lowerRange );
182 item_range_upper.
push_back( upperRange );
195 char* buf_pos = buff;
200 unsigned int i_item = 0;
201 for (
auto itr = item_name.
cbegin(); itr !=
end; ++itr, ++i_item ) {
203 buf_pos = buff + item_buf_pos[i_item];
212 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 15, 0 )
213 auto br =
new TBranch( rtree,
215 TBranch* br =
new TBranch(
217 item_fullname[i_item].c_str(), buf_pos, itr->second.c_str() );
219 if ( itr->first !=
"AUTO_BLK" ) {
220 std::string title = itr->first;
221 title = itr->first +
"::" + br->GetTitle();
222 br->SetTitle( title.c_str() );
225 log <<
MSG::DEBUG <<
"adding TBranch " << br->GetTitle() <<
" at " << (
void*)buf_pos <<
endmsg;
228 if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
232 TLeafI*
index =
nullptr;
233 TObject* tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
234 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
235 index = dynamic_cast<TLeafI*>( tobj );
238 index->SetMaximum( item_range_upper[i_item] );
242 log << MSG::ERROR <<
"Could dynamic cast to TLeafI: " << item_fullname[i_item] << endmsg;
247 rtree->GetListOfBranches()->Add( br );
250 log <<
MSG::INFO <<
"Booked TTree with ID: " << desc <<
" \"" << nt->title() <<
"\" in directory " << getDirectory()
263 const auto& items = nt->
items();
265 return dest + visit( *i, [dest]( const auto& item ) { return saveItem( dest, item ); } );
277 if ( ievt >= rtree->GetEntries() ) {
279 log <<
MSG::ERROR <<
"no more entries in tree to read. max: " << rtree->GetEntries() <<
" current: " << ievt
284 rtree->GetEvent( ievt );
288 auto& items = ntup->
items();
291 return src + visit( *i, [src]( auto& item ) { return loadItem( src, item ); } );
310 status = m_ntupleSvc->create( CLID_ColumnWiseTuple, title, pObj );
316 std::string itemName, indexName, item_type, itemTitle, blockName;
318 long size, totsize = 0;
325 TObjArray* lbr = tree->GetListOfBranches();
327 while ( TObject* tobjb = bitr() ) {
329 TBranch* br = (TBranch*)tobjb;
330 itemTitle = br->GetTitle();
332 int ipos = itemTitle.
find(
"::" );
334 blockName = itemTitle.
substr( 0, ipos );
339 TObjArray* lf = br->GetListOfLeaves();
342 while ( TObject* tobj = litr() ) {
344 bool hasRange =
false;
349 TLeaf* tl =
dynamic_cast<TLeaf*
>( tobj );
354 itemName = tl->GetName();
356 if ( blockName !=
"" ) {
357 log <<
MSG::DEBUG <<
"loading NTuple item " << blockName <<
"/" << itemName;
363 TLeaf* indexLeaf = tl->GetLeafCounter( arraySize );
365 if ( arraySize == 0 ) {
log <<
MSG::ERROR <<
"TLeaf counter size = 0. This should not happen!" <<
endmsg; }
370 indexName = indexLeaf->GetName();
371 indexRange = indexLeaf->GetMaximum();
372 itemSize = indexRange * tl->GetLenType() * arraySize;
374 log <<
"[" << indexName;
377 if ( arraySize != 1 ) {
log <<
"][" << arraySize; }
381 itemSize = tl->GetLenType() * arraySize;
385 if ( arraySize == 1 ) {
389 log <<
"[" << arraySize <<
"]";
398 hasRange = tl->IsRange();
403 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
405 TLeafI* tli =
dynamic_cast<TLeafI*
>( tobj );
407 if ( tli->IsUnsigned() ) {
408 unsigned long min = 0,
max = 0;
410 min = tli->GetMinimum();
411 max = tli->GetMaximum();
414 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
418 min = tli->GetMinimum();
419 max = tli->GetMaximum();
422 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
429 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafF" ) ) {
432 TLeafF* tlf =
dynamic_cast<TLeafF*
>( tobj );
435 min = float( tlf->GetMinimum() );
436 max = float( tlf->GetMaximum() );
442 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
445 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafD" ) ) {
446 double min = 0.,
max = 0.;
448 TLeafD* tld =
dynamic_cast<TLeafD*
>( tobj );
451 min = tld->GetMinimum();
452 max = tld->GetMaximum();
458 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
475 char* buf = ntup->
setBuffer(
new char[totsize] );
479 for (
const auto& iitr : itemList ) {
480 TLeaf* leaf = iitr.first;
481 int isize = iitr.second;
483 log <<
MSG::VERBOSE <<
"setting TBranch " << leaf->GetBranch()->GetName() <<
" buffer at " << (
void*)bufpos
486 leaf->GetBranch()->SetAddress( (
void*)bufpos );