RNTupleCnv.cpp
Go to the documentation of this file.
1 // Include files
2 #include "NTupleInfo.h"
3 #include "RNTupleCnv.h"
4 #include "RootObjAddress.h"
5 
10 #include "GaudiKernel/INTupleSvc.h"
11 #include "GaudiKernel/IRegistry.h"
12 #include "GaudiKernel/MsgStream.h"
13 #include "GaudiKernel/SmartIF.h"
14 #include "GaudiKernel/NTuple.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 //-----------------------------------------------------------------------------
36  : RConverter(clid, svc) {
37 }
38 //-----------------------------------------------------------------------------
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 
54 //-----------------------------------------------------------------------------
57  //-----------------------------------------------------------------------------
59  return Converter::finalize();
60 }
61 
62 //-----------------------------------------------------------------------------
65  DataObject* pObject)
66 //-----------------------------------------------------------------------------
67 {
68  MsgStream log (msgSvc(), "RNTupleCnv");
69 
71 
72  RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>(pAddress);
73 
74  if ( !rAddr ) {
75  log << MSG::ERROR << "Could not dynamic cast to RootObjAddress" << endmsg;
76  return StatusCode::FAILURE;
77  }
78 
79  TTree* rtree = (TTree*) rAddr->tObj();
80 
81  try {
82  unsigned long* info = (unsigned long*)pAddress->ipar();
83  setDirectory(pAddress->par()[0]);
84  status = readData(rtree, dynamic_cast<INTuple*>(pObject), info[1]++);
85  }
86  catch (...) {
87  }
88  return status;
89 }
90 
91 //-----------------------------------------------------------------------------
94  DataObject*& refpObject)
95 //-----------------------------------------------------------------------------
96 {
97  MsgStream log (msgSvc(), "RNTupleCnv");
98 
99  IRegistry* pReg = pAddress->registry();
100 
101  // log << MSG::WARNING << "adr: " << pAddress->par()[0] << " <> "
102  // << pAddress->par()[1] << " <> " << pAddress->ipar()[0] << " <> "
103  // << pAddress->ipar()[1] << " <> " << hex << rAddr->tObj()
104  // << dec << " <> " << pReg->identifier() << endmsg;
105 
106  std::string ident = pReg->identifier();
107 
108  StatusCode status = readObject(pAddress, refpObject); // Doesn't do anything
109  if ( status.isSuccess() ) {
110  RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>( pAddress );
111  if ( !rAddr ) {
112  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
113  return StatusCode::FAILURE;
114  }
115  INTuple* nt = nullptr;
116  TTree* tobj = (TTree*) rAddr->tObj();
117  status = load(tobj, nt);
118  if (status.isSuccess()) {
119  refpObject = dynamic_cast<DataObject*>(nt);
120  } else {
121  log << MSG::ERROR << "Problems loading ntuple id: " << pReg->identifier()
122  << endmsg;
123  }
124  }
125  return status;
126 }
127 
128 //-----------------------------------------------------------------------------
131  IOpaqueAddress*& pAddr)
132 //-----------------------------------------------------------------------------
133 {
134  GlobalDirectoryRestore restore;
135  pAddr = nullptr;
136  try {
137  IRegistry* pReg = pObject->registry();
138  if ( pReg ) {
139  pAddr = pReg->address();
140  if ( !pAddr ) {
141  auto dataMgr = dataProvider().as<IDataManagerSvc>();
142  if ( dataMgr ) {
143  IRegistry* pParentReg = nullptr;
144  StatusCode status = dataMgr->objectParent(pReg, pParentReg);
145  if ( status.isSuccess() ) {
146  IOpaqueAddress* pParAddr = pParentReg->address();
147  if ( pParAddr ) {
148  TDirectory* pParentDir = (TDirectory*)pParAddr->ipar()[0];
149  if ( pParentDir ) {
150  TTree* pTree = nullptr;
151  std::string dsc = pReg->name().substr(1);
152  gDirectory = pParentDir;
153  status = book(dsc, dynamic_cast<INTuple*>(pObject), pTree);
154  if ( !status.isSuccess() ) {
155  return status;
156  }
157  status = createAddress(pObject, gDirectory, pTree, pAddr);
158  if ( !status.isSuccess() ) {
159  return status;
160  }
161  return writeData(pTree, dynamic_cast<INTuple*>(pObject));
162  }
163  }
164  }
165  }
166  }
167  else {
168  TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
169  RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>( pAddr );
170  if ( !rAddr ) {
171  MsgStream log (msgSvc(), "RNTupleCnv");
172  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
173  return StatusCode::FAILURE;
174  }
175  TTree* pTree = (TTree*) rAddr->tObj();
176  gDirectory = pDir;
177  return writeData(pTree, dynamic_cast<INTuple*>(pObject));
178  }
179  }
180  }
181  catch (...) {
182  }
183  MsgStream log (msgSvc(), "RNTupleCnv");
184  log << MSG::ERROR << "Failed to create persistent N-tuple!" << endmsg;
185  return StatusCode::FAILURE;
186 }
187 
188 //-----------------------------------------------------------------------------
191  DataObject* pObj )
192 //-----------------------------------------------------------------------------
193 {
194  MsgStream log (msgSvc(), "RNTupleCnv");
195  if ( pAddr ) {
196  GlobalDirectoryRestore restore;
197  TDirectory* pDir = (TDirectory*)pAddr->ipar()[0];
198  RootObjAddress *rAddr = dynamic_cast<RootObjAddress*>( pAddr );
199  if ( !rAddr ) {
200  log << MSG::ERROR << "Could not cast to RootObjAddress" << endmsg;
201  return StatusCode::FAILURE;
202  }
203  TTree* pTree = (TTree*) rAddr->tObj();
204  if ( pDir && pTree ) {
205  gDirectory->cd(pDir->GetPath());
206  pTree->Write("",TObject::kOverwrite);
207  return StatusCode::SUCCESS;
208  }
209  }
210  else {
211  log << MSG::WARNING << "empty ntuple: " << pObj->registry()->identifier()
212  << endmsg;
213  return createRep(pObj,pAddr);
214  }
215  return StatusCode::FAILURE;
216 }
217 
218 
220 
221 //-----------------------------------------------------------------------------
223  //-----------------------------------------------------------------------------
224  switch( type ) {
225  case DataTypeInfo::BOOL: return "/O"; // bool
226  case DataTypeInfo::SHORT: return "/S"; // short
227  case DataTypeInfo::INT: return "/I"; // int
228  case DataTypeInfo::LONG: return "/I"; // long
229  case DataTypeInfo::LONGLONG: return "/L"; // longlong
230  case DataTypeInfo::USHORT: return "/s"; // ushort
231  case DataTypeInfo::UINT: return "/i"; // uint
232  case DataTypeInfo::ULONG: return "/i"; // ulong
233  case DataTypeInfo::ULONGLONG: return "/l"; // ulonglong
234  case DataTypeInfo::FLOAT: return "/F"; // float
235  case DataTypeInfo::DOUBLE: return "/D"; // double
236  case DataTypeInfo::CHAR: return "/B"; // char
237  case DataTypeInfo::UCHAR: return "/b"; // char
238  default: return "";
239  }
240  // cannot reach this point
241 }
242 
243 //-----------------------------------------------------------------------------
245  //-----------------------------------------------------------------------------
246  int sp;
247  if ( (sp=full.find("/")) != -1 ) {
248  blk = full.substr(0,sp);
249  var = full.substr(sp+1);
250  return true;
251  } else {
252  blk = "AUTO_BLK";
253  var = full;
254  return false;
255  }
256 
257 }
258 
259 //-----------------------------------------------------------------------------
261 
262 #define INSTANTIATE(TYP) \
263  template INTupleItem* createNTupleItem<TYP>(std::string itemName, std::string blockName, std::string index_name, int indexRange, int arraySize, TYP minimum, TYP maximum, INTuple* tuple)
264 
265 namespace RootHistCnv {
266 
267  template<class TYP>
269  std::string indexName,
270  int indexRange, int arraySize,
271  TYP min, TYP max,
272  INTuple* ntup) {
273 
274  std::string varName;
275  if (blockName != "") {
276  varName = blockName + "/" + itemName;
277  } else {
278  varName = itemName;
279  }
280 
281  TYP null = 0;
282  INTupleItem* col = nullptr;
283 
284  if (min == 0 && max == 0) {
285  min = NTuple::Range<TYP>::min();
286  max = NTuple::Range<TYP>::max();
287  }
288 
289 
290  if (indexName == "") {
291 
292  if (arraySize == 1) {
293  // simple items
294  col = NTuple::_Item<TYP>::create(ntup, varName,
295  typeid(TYP),
296  min, max, null);
297 
298  } else {
299  // Arrays of fixed size
300  col = NTuple::_Array<TYP>::create(ntup, varName,
301  typeid(TYP),
302  "", arraySize,
303  min, max, null);
304  }
305 
306  } else {
307 
308  if (arraySize == 1) {
309  // Arrays of variable size
310  col = NTuple::_Array<TYP>::create(ntup, varName,
311  typeid(TYP),
312  indexName, indexRange,
313  min, max, null);
314  } else {
315  // Matrices
316  col = NTuple::_Matrix<TYP>::create(ntup, varName,
317  typeid(TYP),
318  indexName,
319  indexRange, arraySize,
320  min, max, null);
321  }
322 
323  }
324 
325  return col;
326 
327  }
328 
329  INSTANTIATE(float);
330  INSTANTIATE(double);
331  INSTANTIATE(bool);
332  INSTANTIATE(char);
333  INSTANTIATE(int);
334  INSTANTIATE(short);
335  INSTANTIATE(long);
336  INSTANTIATE(long long);
337  INSTANTIATE(unsigned char);
338  INSTANTIATE(unsigned int);
339  INSTANTIATE(unsigned short);
340  INSTANTIATE(unsigned long);
341  INSTANTIATE(unsigned long long);
342 
343 }
Root Converter.
Definition: RConverter.h:34
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:190
bool parseName(const std::string &full, std::string &blk, std::string &var)
Definition: RNTupleCnv.cpp:244
bool isSuccess() const
Test for a status code of SUCCESS.
Definition: StatusCode.h:74
StatusCode initialize() override
Initialize the converter.
Definition: Converter.cpp:65
virtual IRegistry * registry() const =0
Update branch name.
static TYP min()
Minimal number of data.
Definition: NTuple.h:76
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:129
StatusCode initialize() override
Initialize the converter.
Definition: RNTupleCnv.cpp:43
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:56
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:74
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:32
STL class.
NTuple interface class definition.
Definition: INTuple.h:79
StatusCode finalize() override
Initialize the converter.
Definition: Converter.cpp:74
StatusCode service(const Gaudi::Utils::TypeNameString &name, T *&svc, bool createIf=true)
Templated method to access a service by name.
Definition: ISvcLocator.h:78
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:110
NTuple interface class definition.
Definition: INTuple.h:26
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:64
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:26
virtual TObject * tObj() const
Retrieve TObject* ptr.
static TYP max()
Maximal number of data.
Definition: NTuple.h:78
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:124
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:92
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:88
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:58
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:30
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAddr) override
Convert the transient object to the requested representation.
Definition: RNTupleCnv.cpp:130
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:244
StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&refpObj) override
Create the transient representation of an object.
Definition: RNTupleCnv.cpp:93
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:38
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:268
virtual std::string rootVarType(int)
Return ROOT type info:
Definition: RNTupleCnv.cpp:222