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;
205 for (
auto itr = item_name.
cbegin(); itr !=
end; ++itr, ++i_item ) {
207 buf_pos = buff + item_buf_pos[i_item];
216 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 15, 0 )
217 auto br =
new TBranch( rtree,
219 TBranch* br =
new TBranch(
221 item_fullname[i_item].c_str(), buf_pos, itr->second.c_str(), basket_size );
222 if ( itr->first !=
"AUTO_BLK" ) {
223 std::string title = itr->first;
224 title = itr->first +
"::" + br->GetTitle();
225 br->SetTitle( title.c_str() );
228 log <<
MSG::DEBUG <<
"adding TBranch " << br->GetTitle() <<
" at " << (
void*)buf_pos <<
endmsg;
231 if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
235 TLeafI*
index =
nullptr;
236 TObject* tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
237 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
238 index = dynamic_cast<TLeafI*>( tobj );
241 index->SetMaximum( item_range_upper[i_item] );
245 log << MSG::ERROR <<
"Could dynamic cast to TLeafI: " << item_fullname[i_item] << endmsg;
250 rtree->GetListOfBranches()->Add( br );
253 log <<
MSG::INFO <<
"Booked TTree with ID: " << desc <<
" \"" << nt->title() <<
"\" in directory " << getDirectory()
266 const auto& items = nt->
items();
268 return dest + visit( *i, [dest]( const auto& item ) { return saveItem( dest, item ); } );
280 if ( ievt >= rtree->GetEntries() ) {
282 log <<
MSG::ERROR <<
"no more entries in tree to read. max: " << rtree->GetEntries() <<
" current: " << ievt
287 rtree->GetEvent( ievt );
291 auto& items = ntup->
items();
294 return src + visit( *i, [src]( auto& item ) { return loadItem( src, item ); } );
313 status = m_ntupleSvc->create( CLID_ColumnWiseTuple, title, pObj );
319 std::string itemName, indexName, item_type, itemTitle, blockName;
321 long size, totsize = 0;
328 TObjArray* lbr = tree->GetListOfBranches();
330 while ( TObject* tobjb = bitr() ) {
332 TBranch* br = (TBranch*)tobjb;
333 itemTitle = br->GetTitle();
335 int ipos = itemTitle.
find(
"::" );
337 blockName = itemTitle.
substr( 0, ipos );
342 TObjArray* lf = br->GetListOfLeaves();
345 while ( TObject* tobj = litr() ) {
347 bool hasRange =
false;
352 TLeaf* tl =
dynamic_cast<TLeaf*
>( tobj );
357 itemName = tl->GetName();
359 if ( blockName !=
"" ) {
360 log <<
MSG::DEBUG <<
"loading NTuple item " << blockName <<
"/" << itemName;
366 TLeaf* indexLeaf = tl->GetLeafCounter( arraySize );
368 if ( arraySize == 0 ) {
log <<
MSG::ERROR <<
"TLeaf counter size = 0. This should not happen!" <<
endmsg; }
373 indexName = indexLeaf->GetName();
374 indexRange = indexLeaf->GetMaximum();
375 itemSize = indexRange * tl->GetLenType() * arraySize;
377 log <<
"[" << indexName;
380 if ( arraySize != 1 ) {
log <<
"][" << arraySize; }
384 itemSize = tl->GetLenType() * arraySize;
388 if ( arraySize == 1 ) {
392 log <<
"[" << arraySize <<
"]";
401 hasRange = tl->IsRange();
406 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
408 TLeafI* tli =
dynamic_cast<TLeafI*
>( tobj );
410 if ( tli->IsUnsigned() ) {
411 unsigned long min = 0, max = 0;
413 min = tli->GetMinimum();
414 max = tli->GetMaximum();
417 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
419 long min = 0, max = 0;
421 min = tli->GetMinimum();
422 max = tli->GetMaximum();
425 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
432 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafF" ) ) {
433 float min = 0., max = 0.;
435 TLeafF* tlf =
dynamic_cast<TLeafF*
>( tobj );
438 min = float( tlf->GetMinimum() );
439 max = float( tlf->GetMaximum() );
445 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
448 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafD" ) ) {
449 double min = 0., max = 0.;
451 TLeafD* tld =
dynamic_cast<TLeafD*
>( tobj );
454 min = tld->GetMinimum();
455 max = tld->GetMaximum();
461 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize, min, max, ntup, hasRange );
478 char* buf = ntup->
setBuffer(
new char[totsize] );
482 for (
const auto& iitr : itemList ) {
483 TLeaf* leaf = iitr.first;
484 int isize = iitr.second;
486 log <<
MSG::VERBOSE <<
"setting TBranch " << leaf->GetBranch()->GetName() <<
" buffer at " << (
void*)bufpos
489 leaf->GetBranch()->SetAddress( (
void*)bufpos );