The Gaudi Framework  v29r0 (ff2e7097)
RNTupleCnv.cpp
Go to the documentation of this file.
1 // Include files
2 #include "RNTupleCnv.h"
3 #include "NTupleInfo.h"
4 #include "RootObjAddress.h"
5 
11 #include "GaudiKernel/IRegistry.h"
12 #include "GaudiKernel/MsgStream.h"
13 #include "GaudiKernel/NTuple.h"
14 #include "GaudiKernel/SmartIF.h"
15 
16 // Root
17 #include "TTree.h"
18 
19 #ifdef __ICC
20 // disable icc remark #1572: floating-point equality and inequality comparisons are unreliable
21 // they are intended
22 #pragma warning( disable : 1572 )
23 #endif
24 
25 //-----------------------------------------------------------------------------
26 //
27 // Implementation of class : RootHistCnv::RNTupleCnv
28 //
29 // Author : Charles Leggett
30 //
31 //-----------------------------------------------------------------------------
32 
33 //-----------------------------------------------------------------------------
35 RootHistCnv::RNTupleCnv::RNTupleCnv( ISvcLocator* svc, const CLID& clid ) : RConverter( clid, svc ) {}
36 //-----------------------------------------------------------------------------
37 
38 //-----------------------------------------------------------------------------
41 {
42  //-----------------------------------------------------------------------------
44  if ( status.isSuccess() ) {
45  m_ntupleSvc = serviceLocator()->service( "NTupleSvc" );
46  if ( !m_ntupleSvc ) status = StatusCode::FAILURE;
47  }
48  return status;
49 }
50 
51 //-----------------------------------------------------------------------------
54 {
55  //-----------------------------------------------------------------------------
57  return Converter::finalize();
58 }
59 
60 //-----------------------------------------------------------------------------
63 //-----------------------------------------------------------------------------
64 {
65  MsgStream log( msgSvc(), "RNTupleCnv" );
66 
68 
69  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddress );
70 
71  if ( !rAddr ) {
72  log << MSG::ERROR << "Could not dynamic cast to RootObjAddress" << endmsg;
73  return StatusCode::FAILURE;
74  }
75 
76  TTree* rtree = (TTree*)rAddr->tObj();
77 
78  try {
79  unsigned long* info = (unsigned long*)pAddress->ipar();
80  setDirectory( pAddress->par()[0] );
81  status = readData( rtree, dynamic_cast<INTuple*>( pObject ), info[1]++ );
82  } catch ( ... ) {
83  }
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  std::string dsc = pReg->name().substr( 1 );
145  gDirectory = pParentDir;
146  status = book( dsc, dynamic_cast<INTuple*>( pObject ), pTree );
147  if ( !status.isSuccess() ) {
148  return status;
149  }
150  status = createAddress( pObject, gDirectory, pTree, pAddr );
151  if ( !status.isSuccess() ) {
152  return status;
153  }
154  return writeData( pTree, dynamic_cast<INTuple*>( pObject ) );
155  }
156  }
157  }
158  }
159  } else {
160  TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
161  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddr );
162  if ( !rAddr ) {
163  MsgStream log( msgSvc(), "RNTupleCnv" );
164  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
165  return StatusCode::FAILURE;
166  }
167  TTree* pTree = (TTree*)rAddr->tObj();
168  gDirectory = pDir;
169  return writeData( pTree, dynamic_cast<INTuple*>( pObject ) );
170  }
171  }
172  } catch ( ... ) {
173  }
174  MsgStream log( msgSvc(), "RNTupleCnv" );
175  log << MSG::ERROR << "Failed to create persistent N-tuple!" << endmsg;
176  return StatusCode::FAILURE;
177 }
178 
179 //-----------------------------------------------------------------------------
182 //-----------------------------------------------------------------------------
183 {
184  MsgStream log( msgSvc(), "RNTupleCnv" );
185  if ( pAddr ) {
186  GlobalDirectoryRestore restore;
187  TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
188  RootObjAddress* rAddr = dynamic_cast<RootObjAddress*>( pAddr );
189  if ( !rAddr ) {
190  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
191  return StatusCode::FAILURE;
192  }
193  TTree* pTree = (TTree*)rAddr->tObj();
194  if ( pDir && pTree ) {
195  gDirectory->cd( pDir->GetPath() );
196  pTree->Write( "", TObject::kOverwrite );
197  return StatusCode::SUCCESS;
198  }
199  } else {
200  log << MSG::WARNING << "empty ntuple: " << pObj->registry()->identifier() << endmsg;
201  return createRep( pObj, pAddr );
202  }
203  return StatusCode::FAILURE;
204 }
205 
207 
208 //-----------------------------------------------------------------------------
210 {
211  //-----------------------------------------------------------------------------
212  switch ( type ) {
213  case DataTypeInfo::BOOL:
214  return "/O"; // bool
215  case DataTypeInfo::SHORT:
216  return "/S"; // short
217  case DataTypeInfo::INT:
218  return "/I"; // int
219  case DataTypeInfo::LONG:
220  return "/I"; // long
222  return "/L"; // longlong
224  return "/s"; // ushort
225  case DataTypeInfo::UINT:
226  return "/i"; // uint
227  case DataTypeInfo::ULONG:
228  return "/i"; // ulong
230  return "/l"; // ulonglong
231  case DataTypeInfo::FLOAT:
232  return "/F"; // float
234  return "/D"; // double
235  case DataTypeInfo::CHAR:
236  return "/B"; // char
237  case DataTypeInfo::UCHAR:
238  return "/b"; // char
239  default:
240  return "";
241  }
242  // cannot reach this point
243 }
244 
245 //-----------------------------------------------------------------------------
247 {
248  //-----------------------------------------------------------------------------
249  int sp;
250  if ( ( sp = full.find( "/" ) ) != -1 ) {
251  blk = full.substr( 0, sp );
252  var = full.substr( sp + 1 );
253  return true;
254  } else {
255  blk = "AUTO_BLK";
256  var = full;
257  return false;
258  }
259 }
260 
261 //-----------------------------------------------------------------------------
263 
264 #define INSTANTIATE( TYP ) \
265  template INTupleItem* createNTupleItem<TYP>( std::string itemName, std::string blockName, std::string index_name, \
266  int indexRange, int arraySize, TYP minimum, TYP maximum, \
267  INTuple* tuple )
268 
269 namespace RootHistCnv
270 {
271 
272  template <class TYP>
273  INTupleItem* createNTupleItem( std::string itemName, std::string blockName, std::string indexName, int indexRange,
274  int arraySize, TYP min, TYP max, INTuple* ntup )
275  {
276 
277  std::string varName;
278  if ( blockName != "" ) {
279  varName = blockName + "/" + itemName;
280  } else {
281  varName = itemName;
282  }
283 
284  TYP null = 0;
285  INTupleItem* col = nullptr;
286 
287  if ( min == 0 && max == 0 ) {
288  min = NTuple::Range<TYP>::min();
289  max = NTuple::Range<TYP>::max();
290  }
291 
292  if ( indexName == "" ) {
293 
294  if ( arraySize == 1 ) {
295  // simple items
296  col = NTuple::_Item<TYP>::create( ntup, varName, typeid( TYP ), min, max, null );
297 
298  } else {
299  // Arrays of fixed size
300  col = NTuple::_Array<TYP>::create( ntup, varName, typeid( TYP ), "", arraySize, min, max, null );
301  }
302 
303  } else {
304 
305  if ( arraySize == 1 ) {
306  // Arrays of variable size
307  col = NTuple::_Array<TYP>::create( ntup, varName, typeid( TYP ), indexName, indexRange, min, max, null );
308  } else {
309  // Matrices
310  col = NTuple::_Matrix<TYP>::create( ntup, varName, typeid( TYP ), indexName, indexRange, arraySize, min, max,
311  null );
312  }
313  }
314 
315  return col;
316  }
317 
318  INSTANTIATE( float );
319  INSTANTIATE( double );
320  INSTANTIATE( bool );
321  INSTANTIATE( char );
322  INSTANTIATE( int );
323  INSTANTIATE( short );
324  INSTANTIATE( long );
325  INSTANTIATE( long long );
326  INSTANTIATE( unsigned char );
327  INSTANTIATE( unsigned int );
328  INSTANTIATE( unsigned short );
329  INSTANTIATE( unsigned long );
330  INSTANTIATE( unsigned long long );
331 }
Root Converter.
Definition: RConverter.h:33
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition: ISvcLocator.h:25
void setDirectory(const std::string &loc)
Definition: RConverter.cpp:113
RNTupleCnv(ISvcLocator *svc, const CLID &clid)
Standard constructor.
Definition: RNTupleCnv.cpp:35
virtual StatusCode book(const std::string &desc, INTuple *pObj, TTree *&tree)=0
Book a new N tuple.
StatusCode updateRep(IOpaqueAddress *pAddr, DataObject *pObj) override
Update the converted representation of a transient object.
Definition: RNTupleCnv.cpp:181
bool parseName(const std::string &full, std::string &blk, std::string &var)
Definition: RNTupleCnv.cpp:246
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:75
StatusCode initialize() override
Initialize the converter.
Definition: Converter.cpp:44
virtual IRegistry * registry() const =0
Update branch name.
static TYP min()
Minimal number of data.
Definition: NTuple.h:85
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:103
StatusCode initialize() override
Initialize the converter.
Definition: RNTupleCnv.cpp:40
virtual const name_type & name() const =0
Name of the directory (or key)
virtual const std::string * par() const =0
Retrieve String parameters.
StatusCode finalize() override
Finalize the converter.
Definition: RNTupleCnv.cpp:53
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
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:34
STL class.
NTuple interface class definition.
Definition: INTuple.h:82
StatusCode finalize() override
Initialize the converter.
Definition: Converter.cpp:54
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:79
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:115
NTuple interface class definition.
Definition: INTuple.h:27
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const id_type & identifier() const =0
Full identifier (or key)
StatusCode updateObj(IOpaqueAddress *pAddr, DataObject *refpObj) override
Update the transient object from the other representation.
Definition: RNTupleCnv.cpp:62
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:28
virtual TObject * tObj() const
Retrieve TObject* ptr.
static TYP max()
Maximal number of data.
Definition: NTuple.h:87
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.
Definition: Converter.cpp:100
virtual StatusCode load(TTree *tree, INTuple *&refpObj)=0
Create the transient representation of an object.
INSTANTIATE(float)
T find(T...args)
SmartIF< IDataProviderSvc > & dataProvider() const override
Get Data provider service.
Definition: Converter.cpp:74
virtual StatusCode writeData(TTree *rtree, INTuple *pObj)=0
Write N tuple data.
virtual StatusCode readObject(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create the transient representation of an object.
Definition: RConverter.cpp:256
T substr(T...args)
void reset(TYPE *ptr=nullptr)
Set the internal pointer to the passed one disposing of the old one.
Definition: SmartIF.h:92
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:26
Opaque address interface definition.
SmartIF< INTupleSvc > m_ntupleSvc
Reference to N tuple service.
Definition: RNTupleCnv.h:60
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:29
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAddr) override
Convert the transient object to the requested representation.
Definition: RNTupleCnv.cpp:124
virtual StatusCode readData(TTree *rtree, INTuple *pObj, long ievt)=0
Read N tuple data.
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:209
StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&refpObj) override
Create the transient representation of an object.
Definition: RNTupleCnv.cpp:89
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:42
StatusCode createAddress(DataObject *pObject, TDirectory *pDir, TObject *pTObject, IOpaqueAddress *&refpAddr)
Create address of the transient object according to the requested representation. ...
Definition: RConverter.cpp:160
INTupleItem * createNTupleItem(std::string itemName, std::string blockName, std::string indexName, int indexRange, int arraySize, TYP min, TYP max, INTuple *ntup)
Definition: RNTupleCnv.cpp:273
virtual std::string rootVarType(int)
Return ROOT type info:
Definition: RNTupleCnv.cpp:209