11 #define ROOTHISTCNV_RCWNTUPLECNV_CPP
35 static_assert( std::is_trivially_copyable_v<T>,
"T must be trivally copyable" );
36 std::memcpy( target, src.buffer(),
sizeof( T ) * src.length() );
37 return sizeof( T ) * src.length();
42 static_assert( std::is_trivially_copyable_v<T>,
"T must be trivally copyable" );
43 std::memcpy(
const_cast<void*
>( target.buffer() ), src,
sizeof( T ) * target.length() );
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 +=
']'; }
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
175 item_range_lower.
push_back( lowerRange );
176 item_range_upper.
push_back( upperRange );
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" ) {
214 std::string title = itr->first;
215 title = itr->first +
"::" + br->GetTitle();
216 br->SetTitle( title.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 );
244 log <<
MSG::INFO <<
"Booked TTree with ID: " << desc <<
" \"" << nt->title() <<
"\" in directory " << getDirectory()
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 );
285 return src + visit( *i, [src]( auto& item ) { return loadItem( src, item ); } );
304 status = m_ntupleSvc->create( CLID_ColumnWiseTuple, title, pObj );
310 std::string itemName, indexName, item_type, itemTitle, blockName;
312 long size, totsize = 0;
319 TObjArray* lbr = tree->GetListOfBranches();
321 while ( TObject* tobjb = bitr() ) {
323 TBranch* br = (TBranch*)tobjb;
324 itemTitle = br->GetTitle();
326 int ipos = itemTitle.
find(
"::" );
328 blockName = itemTitle.
substr( 0, ipos );
333 TObjArray* lf = br->GetListOfLeaves();
336 while ( TObject* tobj = litr() ) {
338 bool hasRange =
false;
344 TLeaf* tl =
dynamic_cast<TLeaf*
>( tobj );
346 itemName = tl->GetName();
355 if ( blockName !=
"" ) {
356 log <<
MSG::DEBUG <<
"loading NTuple item " << blockName <<
"/" << itemName;
362 TLeaf* indexLeaf = ( tl ? tl->GetLeafCounter( arraySize ) :
nullptr );
364 if ( arraySize == 0 ) {
log <<
MSG::ERROR <<
"TLeaf counter size = 0. This should not happen!" <<
endmsg; }
369 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 <<
"]";
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();
421 min = tli->GetMinimum();
422 max = tli->GetMaximum();
432 }
else if ( tobj->IsA()->InheritsFrom(
"TLeafF" ) ) {
435 TLeafF* tlf =
dynamic_cast<TLeafF*
>( tobj );
438 min = float( tlf->GetMinimum() );
439 max = float( tlf->GetMaximum() );
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();
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 );