The Gaudi Framework  v37r1 (a7f61348)
RNTupleCnv.cpp
Go to the documentation of this file.
1 /***********************************************************************************\
2 * (c) Copyright 1998-2019 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;
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>( std::string itemName, std::string blockName, std::string index_name, \
259  int indexRange, int arraySize, TYP minimum, TYP maximum, \
260  INTuple* tuple, bool hasRange )
261 
262 namespace RootHistCnv {
263 
264  template <class TYP>
265  INTupleItem* createNTupleItem( std::string itemName, std::string blockName, std::string indexName, int indexRange,
266  int arraySize, TYP min, TYP max, INTuple* ntup, bool hasRange ) {
267 
268  std::string varName;
269  if ( blockName != "" ) {
270  varName = blockName + "/" + itemName;
271  } else {
272  varName = itemName;
273  }
274 
275  TYP null = 0;
276  INTupleItem* col = nullptr;
277 
278  if ( !hasRange ) {
281  }
282 
283  if ( indexName == "" ) {
284 
285  if ( arraySize == 1 ) {
286  // simple items
287  col = NTuple::_Item<TYP>::create( ntup, varName, typeid( TYP ), min, max, null );
288 
289  } else {
290  // Arrays of fixed size
291  col = NTuple::_Array<TYP>::create( ntup, varName, typeid( TYP ), "", arraySize, min, max, null );
292  }
293 
294  } else {
295 
296  if ( arraySize == 1 ) {
297  // Arrays of variable size
298  col = NTuple::_Array<TYP>::create( ntup, varName, typeid( TYP ), indexName, indexRange, min, max, null );
299  } else {
300  // Matrices
301  col = NTuple::_Matrix<TYP>::create( ntup, varName, typeid( TYP ), indexName, indexRange, arraySize, min, max,
302  null );
303  }
304  }
305 
306  return col;
307  }
308 
309  INSTANTIATE( float );
310  INSTANTIATE( double );
311  INSTANTIATE( bool );
312  INSTANTIATE( char );
313  INSTANTIATE( int );
314  INSTANTIATE( short );
315  INSTANTIATE( long );
316  INSTANTIATE( long long );
317  INSTANTIATE( unsigned char );
318  INSTANTIATE( unsigned int );
319  INSTANTIATE( unsigned short );
320  INSTANTIATE( unsigned long );
321  INSTANTIATE( unsigned long long );
322 } // 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:30
IDataManagerSvc
Definition: IDataManagerSvc.h:55
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:314
IOpaqueAddress
Definition: IOpaqueAddress.h:33
ISvcLocator
Definition: ISvcLocator.h:46
GaudiAlg.HistoUtils.book
def book(*args, **kwargs)
Definition: HistoUtils.py:127
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
max
EventIDBase max(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:225
IRegistry
Definition: IRegistry.h:32
DataTypeInfo::USHORT
@ USHORT
Definition: DataTypeInfo.h:36
RootHistCnv::RootObjAddress
Definition: RootObjAddress.h:21
IDataProviderSvc.h
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
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:203
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
min
EventIDBase min(const EventIDBase &lhs, const EventIDBase &rhs)
Definition: EventIDBase.h:212
INTupleItem
Definition: INTuple.h:37
RootObjAddress.h
IRegistry.h
MsgStream
Definition: MsgStream.h:34
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:162
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:40
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
RootHistCnv::createNTupleItem
INTupleItem * createNTupleItem(std::string itemName, std::string blockName, 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
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
AsyncIncidents.msgSvc
msgSvc
Definition: AsyncIncidents.py:34
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:82
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.