The Gaudi Framework  master (37c0b60a)
RNTupleCnv.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2024 CERN for the benefit of the LHCb and ATLAS collaborations *
3 * *
4 * This software is distributed under the terms of the Apache version 2 licence, *
5 * copied verbatim in the file "LICENSE". *
6 * *
7 * In applying this licence, CERN does not waive the privileges and immunities *
8 * granted to it by virtue of its status as an Intergovernmental Organization *
9 * or submit itself to any jurisdiction. *
10 \***********************************************************************************/
11 // Include files
12 #include "RNTupleCnv.h"
13 #include "RootObjAddress.h"
14 
15 #include <GaudiKernel/DataObject.h>
18 #include <GaudiKernel/INTupleSvc.h>
20 #include <GaudiKernel/IRegistry.h>
21 #include <GaudiKernel/MsgStream.h>
22 #include <GaudiKernel/NTuple.h>
23 #include <GaudiKernel/SmartIF.h>
24 
25 // Root
26 #include <TTree.h>
27 
28 //-----------------------------------------------------------------------------
29 //
30 // Implementation of class : RootHistCnv::RNTupleCnv
31 //
32 // Author : Charles Leggett
33 //
34 //-----------------------------------------------------------------------------
35 
36 //-----------------------------------------------------------------------------
38 RootHistCnv::RNTupleCnv::RNTupleCnv( ISvcLocator* svc, const CLID& clid ) : RConverter( clid, svc ) {}
39 //-----------------------------------------------------------------------------
40 
41 //-----------------------------------------------------------------------------
44  //-----------------------------------------------------------------------------
46  if ( status.isSuccess() ) {
47  m_ntupleSvc = serviceLocator()->service( "NTupleSvc" );
48  if ( !m_ntupleSvc ) status = StatusCode::FAILURE;
49  }
50  return status;
51 }
52 
53 //-----------------------------------------------------------------------------
56  //-----------------------------------------------------------------------------
57  m_ntupleSvc.reset();
58  return Converter::finalize();
59 }
60 
61 //-----------------------------------------------------------------------------
64 //-----------------------------------------------------------------------------
65 {
66  MsgStream log( msgSvc(), "RNTupleCnv" );
67 
69 
70  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddress );
71 
72  if ( !rAddr ) {
73  log << MSG::ERROR << "Could not dynamic cast to RootObjAddress" << endmsg;
74  return StatusCode::FAILURE;
75  }
76 
77  TTree* rtree = (TTree*)rAddr->tObj();
78 
79  try {
80  unsigned long* info = (unsigned long*)pAddress->ipar();
81  setDirectory( pAddress->par()[0] );
82  status = readData( rtree, dynamic_cast<INTuple*>( pObject ), info[1]++ );
83  } catch ( ... ) {}
84  return status;
85 }
86 
87 //-----------------------------------------------------------------------------
90 //-----------------------------------------------------------------------------
91 {
92  MsgStream log( msgSvc(), "RNTupleCnv" );
93 
94  IRegistry* pReg = pAddress->registry();
95 
96  // log << MSG::WARNING << "adr: " << pAddress->par()[0] << " <> "
97  // << pAddress->par()[1] << " <> " << pAddress->ipar()[0] << " <> "
98  // << pAddress->ipar()[1] << " <> " << hex << rAddr->tObj()
99  // << dec << " <> " << pReg->identifier() << endmsg;
100 
101  std::string ident = pReg->identifier();
102 
103  StatusCode status = readObject( pAddress, refpObject ); // Doesn't do anything
104  if ( status.isSuccess() ) {
105  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddress );
106  if ( !rAddr ) {
107  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
108  return StatusCode::FAILURE;
109  }
110  INTuple* nt = nullptr;
111  TTree* tobj = (TTree*)rAddr->tObj();
112  status = load( tobj, nt );
113  if ( status.isSuccess() ) {
114  refpObject = dynamic_cast<DataObject*>( nt );
115  } else {
116  log << MSG::ERROR << "Problems loading ntuple id: " << pReg->identifier() << endmsg;
117  }
118  }
119  return status;
120 }
121 
122 //-----------------------------------------------------------------------------
125 //-----------------------------------------------------------------------------
126 {
127  GlobalDirectoryRestore restore;
128  pAddr = nullptr;
129  try {
130  IRegistry* pReg = pObject->registry();
131  if ( pReg ) {
132  pAddr = pReg->address();
133  if ( !pAddr ) {
134  auto dataMgr = dataProvider().as<IDataManagerSvc>();
135  if ( dataMgr ) {
136  IRegistry* pParentReg = nullptr;
137  StatusCode status = dataMgr->objectParent( pReg, pParentReg );
138  if ( status.isSuccess() ) {
139  IOpaqueAddress* pParAddr = pParentReg->address();
140  if ( pParAddr ) {
141  TDirectory* pParentDir = (TDirectory*)pParAddr->ipar()[0];
142  if ( pParentDir ) {
143  TTree* pTree = nullptr;
144  auto dsc = pReg->name().substr( 1 );
145  gDirectory = pParentDir;
146  status = book( dsc, dynamic_cast<INTuple*>( pObject ), pTree );
147  if ( !status.isSuccess() ) { return status; }
148  status = createAddress( pObject, gDirectory, pTree, pAddr );
149  if ( !status.isSuccess() ) { return status; }
150  return writeData( pTree, dynamic_cast<INTuple*>( pObject ) );
151  }
152  }
153  }
154  }
155  } else {
156  TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
157  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddr );
158  if ( !rAddr ) {
159  MsgStream log( msgSvc(), "RNTupleCnv" );
160  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
161  return StatusCode::FAILURE;
162  }
163  TTree* pTree = (TTree*)rAddr->tObj();
164  gDirectory = pDir;
165  return writeData( pTree, dynamic_cast<INTuple*>( pObject ) );
166  }
167  }
168  } catch ( ... ) {}
169  MsgStream log( msgSvc(), "RNTupleCnv" );
170  log << MSG::ERROR << "Failed to create persistent N-tuple!" << endmsg;
171  return StatusCode::FAILURE;
172 }
173 
174 //-----------------------------------------------------------------------------
177 //-----------------------------------------------------------------------------
178 {
179  MsgStream log( msgSvc(), "RNTupleCnv" );
180  if ( pAddr ) {
181  GlobalDirectoryRestore restore;
182  TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
183  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddr );
184  if ( !rAddr ) {
185  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
186  return StatusCode::FAILURE;
187  }
188  TTree* pTree = (TTree*)rAddr->tObj();
189  if ( pDir && pTree ) {
190  gDirectory->cd( pDir->GetPath() );
191  pTree->Write( "", TObject::kOverwrite );
192  return StatusCode::SUCCESS;
193  }
194  } else {
195  log << MSG::WARNING << "empty ntuple: " << pObj->registry()->identifier() << endmsg;
196  return createRep( pObj, pAddr );
197  }
198  return StatusCode::FAILURE;
199 }
200 
202 
203 //-----------------------------------------------------------------------------
205  //-----------------------------------------------------------------------------
206  switch ( type ) {
207  case DataTypeInfo::BOOL:
208  return "/O"; // bool
209  case DataTypeInfo::SHORT:
210  return "/S"; // short
211  case DataTypeInfo::INT:
212  return "/I"; // int
213  case DataTypeInfo::LONG:
214  return "/I"; // long
216  return "/L"; // long long
218  return "/s"; // ushort
219  case DataTypeInfo::UINT:
220  return "/i"; // uint
221  case DataTypeInfo::ULONG:
222  return "/i"; // ulong
224  return "/l"; // unsigned long long
225  case DataTypeInfo::FLOAT:
226  return "/F"; // float
228  return "/D"; // double
229  case DataTypeInfo::CHAR:
230  return "/B"; // char
231  case DataTypeInfo::UCHAR:
232  return "/b"; // char
233  default:
234  return "";
235  }
236  // cannot reach this point
237 }
238 
239 //-----------------------------------------------------------------------------
241  //-----------------------------------------------------------------------------
242  int sp = -1;
243  if ( ( sp = full.find( "/" ) ) != -1 ) {
244  blk = full.substr( 0, sp );
245  var = full.substr( sp + 1 );
246  return true;
247  } else {
248  blk = "AUTO_BLK";
249  var = full;
250  return false;
251  }
252 }
253 
254 //-----------------------------------------------------------------------------
256 
257 #define INSTANTIATE( TYP ) \
258  template INTupleItem* createNTupleItem<TYP>( const std::string& itemName, const std::string& blockName, \
259  const std::string& index_name, int indexRange, int arraySize, \
260  TYP minimum, TYP maximum, INTuple* tuple, bool hasRange )
261 
262 namespace RootHistCnv {
263 
264  template <class TYP>
265  INTupleItem* createNTupleItem( const std::string& itemName, const std::string& blockName,
266  const std::string& indexName, int indexRange, int arraySize, TYP min, TYP max,
267  INTuple* ntup, bool hasRange ) {
268 
269  std::string varName;
270  if ( blockName != "" ) {
271  varName = blockName + "/" + itemName;
272  } else {
273  varName = itemName;
274  }
275 
276  TYP null = 0;
277  INTupleItem* col = nullptr;
278 
279  if ( !hasRange ) {
280  min = NTuple::Range<TYP>::min();
281  max = NTuple::Range<TYP>::max();
282  }
283 
284  if ( indexName == "" ) {
285 
286  if ( arraySize == 1 ) {
287  // simple items
288  col = NTuple::_Item<TYP>::create( ntup, varName, typeid( TYP ), min, max, null );
289 
290  } else {
291  // Arrays of fixed size
292  col = NTuple::_Array<TYP>::create( ntup, varName, typeid( TYP ), "", arraySize, min, max, null );
293  }
294 
295  } else {
296 
297  if ( arraySize == 1 ) {
298  // Arrays of variable size
299  col = NTuple::_Array<TYP>::create( ntup, varName, typeid( TYP ), indexName, indexRange, min, max, null );
300  } else {
301  // Matrices
302  col = NTuple::_Matrix<TYP>::create( ntup, varName, typeid( TYP ), indexName, indexRange, arraySize, min, max,
303  null );
304  }
305  }
306 
307  return col;
308  }
309 
310  INSTANTIATE( float );
311  INSTANTIATE( double );
312  INSTANTIATE( bool );
313  INSTANTIATE( char );
314  INSTANTIATE( int );
315  INSTANTIATE( short );
316  INSTANTIATE( long );
317  INSTANTIATE( long long );
318  INSTANTIATE( unsigned char );
319  INSTANTIATE( unsigned int );
320  INSTANTIATE( unsigned short );
321  INSTANTIATE( unsigned long );
322  INSTANTIATE( unsigned long long );
323 } // namespace RootHistCnv
std::string
STL class.
RootHistCnv::RootObjAddress::tObj
virtual TObject * tObj() const
Retrieve TObject* ptr.
Definition: RootObjAddress.h:91
IOpaqueAddress::par
virtual const std::string * par() const =0
Retrieve String parameters.
RootHistCnv::RNTupleCnv::createRep
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAddr) override
Convert the transient object to the requested representation.
Definition: RNTupleCnv.cpp:124
Gaudi.Configuration.log
log
Definition: Configuration.py:28
RootHistCnv::createNTupleItem
INTupleItem * createNTupleItem(const std::string &itemName, const std::string &blockName, const std::string &indexName, int indexRange, int arraySize, TYP min, TYP max, INTuple *ntup, bool hasRange)
Add an item of a given type to the N tuple.
Definition: RNTupleCnv.cpp:265
IDataManagerSvc
Definition: IDataManagerSvc.h:55
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
IOpaqueAddress
Definition: IOpaqueAddress.h:33
ISvcLocator
Definition: ISvcLocator.h:46
MSG::WARNING
@ WARNING
Definition: IMessageSvc.h:25
RootHistCnv::RNTupleCnv::createObj
StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&refpObj) override
Create the transient representation of an object.
Definition: RNTupleCnv.cpp:89
IRegistry
Definition: IRegistry.h:32
DataTypeInfo::USHORT
@ USHORT
Definition: DataTypeInfo.h:36
RootHistCnv::RootObjAddress
Definition: RootObjAddress.h:21
IDataProviderSvc.h
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:80
DataTypeInfo::ULONG
@ ULONG
Definition: DataTypeInfo.h:38
compareOutputFiles.sp
sp
Definition: compareOutputFiles.py:506
DataTypeInfo::LONG
@ LONG
Definition: DataTypeInfo.h:42
DataTypeInfo::DOUBLE
@ DOUBLE
Definition: DataTypeInfo.h:45
SmartIF.h
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
RootHistCnv
Definition: DirectoryCnv.h:27
NTuple::_Item::create
static _Item * create(INTuple *tup, const std::string &name, const std::type_info &info, TYP min, TYP max, TYP def)
Create instance.
Definition: NTupleItems.cpp:36
RootHistCnv::RNTupleCnv::updateObj
StatusCode updateObj(IOpaqueAddress *pAddr, DataObject *refpObj) override
Update the transient object from the other representation.
Definition: RNTupleCnv.cpp:63
StatusCode
Definition: StatusCode.h:65
DataTypeInfo::SHORT
@ SHORT
Definition: DataTypeInfo.h:40
Gaudi::Histos::book
GAUDI_API AIDA::IHistogram1D * book(IHistogramSvc *svc, const std::string &path, const Gaudi::Histo1DDef &hist)
helper function to book 1D-histogram
Definition: HistoDef.cpp:77
RootHistCnv::RNTupleCnv::finalize
StatusCode finalize() override
Finalize the converter.
Definition: RNTupleCnv.cpp:55
IOpaqueAddress.h
RootHistCnv::parseName
bool parseName(const std::string &full, std::string &blk, std::string &var)
Definition: RNTupleCnv.cpp:240
NTuple.h
INTuple
Definition: INTuple.h:91
RootHistCnv::RConverter
Definition: RConverter.h:41
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:18
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:202
NTuple::_Matrix::create
static _Matrix * create(INTuple *tup, const std::string &name, const std::type_info &info, const std::string &index, long ncol, long nrow, TYP min, TYP max, TYP def)
Create instance.
Definition: NTupleItems.cpp:50
INTupleItem
Definition: INTuple.h:37
RootObjAddress.h
IRegistry.h
MsgStream
Definition: MsgStream.h:33
GlobalDirectoryRestore
Definition: RConverter.h:26
IOpaqueAddress::registry
virtual IRegistry * registry() const =0
Update branch name.
NTuple::Range::max
static TYP max()
Maximal number of data.
Definition: NTuple.h:94
RootHistCnv::RNTupleCnv::initialize
StatusCode initialize() override
Initialize the converter.
Definition: RNTupleCnv.cpp:43
DataTypeInfo::FLOAT
@ FLOAT
Definition: DataTypeInfo.h:44
std::string::substr
T substr(T... args)
RootHistCnv::INSTANTIATE
INSTANTIATE(float)
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
RNTupleCnv.h
gaudirun.type
type
Definition: gaudirun.py:160
DataTypeInfo::UCHAR
@ UCHAR
Definition: DataTypeInfo.h:35
DataTypeInfo::UINT
@ UINT
Definition: DataTypeInfo.h:37
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:100
DataObject.h
DataTypeInfo::BOOL
@ BOOL
Definition: DataTypeInfo.h:43
MSG::ERROR
@ ERROR
Definition: IMessageSvc.h:25
DataTypeInfo::ULONGLONG
@ ULONGLONG
Definition: DataTypeInfo.h:55
IRegistry::identifier
virtual const id_type & identifier() const =0
Full identifier (or key)
DataObject
Definition: DataObject.h:36
NTuple::_Array::create
static _Array * create(INTuple *tup, const std::string &name, const std::type_info &info, const std::string &index, long len, TYP min, TYP max, TYP def)
Create instance.
Definition: NTupleItems.cpp:43
GaudiConfig2.semantics.ident
ident
Definition: semantics.py:198
DataTypeInfo::LONGLONG
@ LONGLONG
Definition: DataTypeInfo.h:54
RootHistCnv::RNTupleCnv::updateRep
StatusCode updateRep(IOpaqueAddress *pAddr, DataObject *pObj) override
Update the converted representation of a transient object.
Definition: RNTupleCnv.cpp:176
Converter::initialize
StatusCode initialize() override
Initialize the converter.
Definition: Converter.cpp:53
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:101
RootHistCnv::RNTupleCnv::rootVarType
virtual std::string rootVarType(int)
Return ROOT type info:
Definition: RNTupleCnv.cpp:204
RootHistCnv::RNTupleCnv::RNTupleCnv
RNTupleCnv(ISvcLocator *svc, const CLID &clid)
Standard constructor.
Definition: RNTupleCnv.cpp:38
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:78
NTuple::Range::min
static TYP min()
Minimal number of data.
Definition: NTuple.h:92
IDataManagerSvc.h
DataTypeInfo::INT
@ INT
Definition: DataTypeInfo.h:41
INTupleSvc.h
Converter::finalize
StatusCode finalize() override
Initialize the converter.
Definition: Converter.cpp:60
DataTypeInfo::CHAR
@ CHAR
Definition: DataTypeInfo.h:39
MsgStream.h
IOpaqueAddress::ipar
virtual const unsigned long * ipar() const =0
Access to generic link parameters.