11 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
35 static_assert( std::is_trivially_copyable_v<T>,
"T must be trivally copyable" );
37 return sizeof( T ) * src.length();
42 static_assert( std::is_trivially_copyable_v<T>,
"T must be trivally copyable" );
44 return sizeof( T ) *
target.length();
47 template <
typename POD>
48 decltype(
auto ) downcast_item(
const INTupleItem& i ) {
51 template <
typename POD>
55 template <
typename POD,
typename T>
56 void downcast_item( T&& ) =
delete;
58 template <
typename Item,
typename F>
59 decltype(
auto ) visit( Item& i, F&& f ) {
62 return f( downcast_item<int>( i ) );
64 return f( downcast_item<char>( i ) );
66 return f( downcast_item<short>( i ) );
68 return f( downcast_item<long>( i ) );
70 return f( downcast_item<long long>( i ) );
72 return f( downcast_item<unsigned char>( i ) );
74 return f( downcast_item<unsigned short>( i ) );
76 return f( downcast_item<unsigned int>( i ) );
78 return f( downcast_item<unsigned long>( i ) );
80 return f( downcast_item<unsigned long long>( i ) );
82 return f( downcast_item<double>( i ) );
84 return f( downcast_item<float>( i ) );
86 return f( downcast_item<bool>( i ) );
101 long item_size =
sizeof( T );
102 long dimension = it->length();
103 long ndim = it->ndim() - 1;
105 if ( it->hasIndex() || it->length() > 1 ) { desc +=
'['; }
106 if ( it->hasIndex() ) {
109 if ( ind_blk != block_name ) {
110 std::cerr <<
"ERROR: Index for CWNT variable " << ind_var <<
" is in a different block: " << ind_blk
114 }
else if ( it->dim( ndim ) > 1 ) {
118 for (
int i = ndim - 1; i >= 0; i-- ) {
122 if ( it->hasIndex() || it->length() > 1 ) { desc +=
']'; }
124 lowerRange = it->
range().lower();
125 upperRange = it->
range().upper();
127 size += item_size * dimension;
137 log <<
MSG::VERBOSE <<
"created tree id: " << rtree->GetName() <<
" title: " << nt->
title() <<
" desc: " << desc
143 long lowerRange, upperRange;
145 long cursize, oldsize = 0;
152 for (
const auto& i : nt->
items() ) {
155 visit( *i, [&](
const auto& data ) {
156 analyzeItem( this->
rootVarType( data.type() ), &data, item, block_name, var_name, lowerRange, upperRange,
size );
160 cursize =
size - oldsize;
162 log <<
MSG::VERBOSE <<
"item: " << item <<
" type " << i->type() <<
" blk: " << block_name <<
" var: " << var_name
163 <<
" rng: " << lowerRange <<
" " << upperRange <<
" sz: " <<
size <<
" " << cursize
170 item_range_lower.
push_back( lowerRange );
171 item_range_upper.
push_back( upperRange );
184 char* buf_pos = buff;
189 unsigned int i_item = 0;
190 for (
auto itr = item_name.
cbegin(); itr !=
end; ++itr, ++i_item ) {
192 buf_pos = buff + item_buf_pos[i_item];
201 #if ROOT_VERSION_CODE >= ROOT_VERSION( 5, 15, 0 )
202 auto br =
new TBranch( rtree,
204 TBranch* br =
new TBranch(
206 item_fullname[i_item].c_str(), buf_pos, itr->second.c_str() );
208 if ( itr->first !=
"AUTO_BLK" ) {
209 std::string title = itr->first;
210 title = itr->first +
"::" + br->GetTitle();
211 br->SetTitle( title.c_str() );
214 log <<
MSG::DEBUG <<
"adding TBranch " << br->GetTitle() <<
" at " << (
void*)buf_pos <<
endmsg;
217 if ( item_range_lower[i_item] < item_range_upper[i_item] ) {
221 TLeafI* index =
nullptr;
222 TObject* tobj = br->GetListOfLeaves()->FindObject( item_fullname[i_item].c_str() );
223 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
224 index = dynamic_cast<TLeafI*>( tobj );
227 index->SetMaximum( item_range_upper[i_item] );
231 log << MSG::ERROR <<
"Could dynamic cast to TLeafI: " << item_fullname[i_item] << endmsg;
236 rtree->GetListOfBranches()->Add( br );
239 log <<
MSG::INFO <<
"Booked TTree with ID: " << desc <<
" \"" << nt->title() <<
"\" in directory " << getDirectory()
254 return dest + visit( *i, [dest]( const auto& item ) { return saveItem( dest, item ); } );
266 if ( ievt >= rtree->GetEntries() ) {
268 log <<
MSG::ERROR <<
"no more entries in tree to read. max: " << rtree->GetEntries() <<
" current: " << ievt
273 rtree->GetEvent( ievt );
280 return src + visit( *i, [src]( auto& item ) { return loadItem( src, item ); } );
299 status = m_ntupleSvc->create( CLID_ColumnWiseTuple, title, pObj );
305 std::string itemName, indexName, item_type, itemTitle, blockName;
307 long size, totsize = 0;
314 TObjArray* lbr = tree->GetListOfBranches();
316 while ( TObject* tobjb = bitr() ) {
318 TBranch* br = (TBranch*)tobjb;
319 itemTitle = br->GetTitle();
321 int ipos = itemTitle.
find(
"::" );
323 blockName = itemTitle.
substr( 0, ipos );
328 TObjArray* lf = br->GetListOfLeaves();
331 while ( TObject* tobj = litr() ) {
333 bool hasRange =
false;
338 TLeaf* tl =
dynamic_cast<TLeaf*
>( tobj );
343 itemName = tl->GetName();
345 if ( blockName !=
"" ) {
346 log <<
MSG::DEBUG <<
"loading NTuple item " << blockName <<
"/" << itemName;
352 TLeaf* indexLeaf = tl->GetLeafCounter( arraySize );
354 if ( arraySize == 0 ) {
log <<
MSG::ERROR <<
"TLeaf counter size = 0. This should not happen!" <<
endmsg; }
359 indexName = indexLeaf->GetName();
360 indexRange = indexLeaf->GetMaximum();
361 itemSize = indexRange * tl->GetLenType() * arraySize;
363 log <<
"[" << indexName;
366 if ( arraySize != 1 ) {
log <<
"][" << arraySize; }
370 itemSize = tl->GetLenType() * arraySize;
374 if ( arraySize == 1 ) {
378 log <<
"[" << arraySize <<
"]";
387 hasRange = tl->IsRange();
392 if ( tobj->IsA()->InheritsFrom(
"TLeafI" ) ) {
394 TLeafI* tli =
dynamic_cast<TLeafI*
>( tobj );
396 if ( tli->IsUnsigned() ) {
397 unsigned long min = 0,
max = 0;
399 min = tli->GetMinimum();
400 max = tli->GetMaximum();
403 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
407 min = tli->GetMinimum();
408 max = tli->GetMaximum();
411 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
418 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafF" ) ) {
421 TLeafF* tlf =
dynamic_cast<TLeafF*
>( tobj );
424 min = float( tlf->GetMinimum() );
425 max = float( tlf->GetMaximum() );
431 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
434 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafD" ) ) {
435 double min = 0.,
max = 0.;
437 TLeafD* tld =
dynamic_cast<TLeafD*
>( tobj );
440 min = tld->GetMinimum();
441 max = tld->GetMaximum();
447 item =
createNTupleItem( itemName, blockName, indexName, indexRange, arraySize,
min,
max, ntup, hasRange );
464 char* buf = ntup->
setBuffer(
new char[totsize] );
468 for (
const auto& iitr : itemList ) {
469 TLeaf* leaf = iitr.first;
470 int isize = iitr.second;
472 log <<
MSG::VERBOSE <<
"setting TBranch " << leaf->GetBranch()->GetName() <<
" buffer at " << (
void*)bufpos
475 leaf->GetBranch()->SetAddress( (
void*)bufpos );