The Gaudi Framework  master (e68eea06)
Loading...
Searching...
No Matches
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
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//-----------------------------------------------------------------------------
38RootHistCnv::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;
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{
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 ) {
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 ) {
208 return "/O"; // bool
210 return "/S"; // short
212 return "/I"; // int
214 return "/I"; // long
216 return "/L"; // long long
218 return "/s"; // ushort
220 return "/i"; // uint
222 return "/i"; // ulong
224 return "/l"; // unsigned long long
226 return "/F"; // float
228 return "/D"; // double
230 return "/B"; // char
232 return "/b"; // char
233 default:
234 return "";
235 }
236 // cannot reach this point
237}
238
239//-----------------------------------------------------------------------------
240bool RootHistCnv::parseName( const std::string& full, std::string& blk, std::string& var ) {
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
262namespace 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 ) {
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 );
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
unsigned int CLID
Class ID definition.
Definition ClassID.h:16
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition MsgStream.h:198
#define INSTANTIATE(TYP)
StatusCode initialize() override
Initialize the converter.
Definition Converter.cpp:52
SmartIF< ISvcLocator > & serviceLocator() const
Retrieve pointer to service locator.
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
SmartIF< IDataProviderSvc > & dataProvider() const override
Get Data provider service.
Definition Converter.cpp:77
StatusCode finalize() override
Initialize the converter.
Definition Converter.cpp:59
A DataObject is the base class of any identifiable object on any data store.
Definition DataObject.h:37
IRegistry * registry() const
Get pointer to Registry.
Definition DataObject.h:79
NTuple interface class definition.
Definition INTuple.h:86
NTuple interface class definition.
Definition INTuple.h:32
Opaque address interface definition.
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
virtual const std::string * par() const =0
Retrieve String parameters.
virtual IRegistry * registry() const =0
Update branch name.
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition IRegistry.h:29
virtual const name_type & name() const =0
Name of the directory (or key)
virtual const id_type & identifier() const =0
Full identifier (or key)
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
Definition ISvcLocator.h:42
Definition of the MsgStream class used to transmit messages.
Definition MsgStream.h:29
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.
static _Item * create(INTuple *tup, const std::string &name, const std::type_info &info, TYP min, TYP max, TYP def)
Create instance.
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.
static TYP min()
Minimal number of data.
Definition NTuple.h:84
static TYP max()
Maximal number of data.
Definition NTuple.h:86
void setDirectory(const std::string &loc)
virtual StatusCode readObject(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create the transient representation of an object.
RConverter(const CLID &clid, ISvcLocator *svc)
Standard constructor.
Definition RConverter.h:64
StatusCode createAddress(DataObject *pObject, TDirectory *pDir, TObject *pTObject, IOpaqueAddress *&refpAddr)
Create address of the transient object according to the requested representation.
StatusCode createObj(IOpaqueAddress *pAddr, DataObject *&refpObj) override
Create the transient representation of an object.
StatusCode updateObj(IOpaqueAddress *pAddr, DataObject *refpObj) override
Update the transient object from the other representation.
virtual StatusCode writeData(TTree *rtree, INTuple *pObj)=0
Write N tuple data.
RNTupleCnv(ISvcLocator *svc, const CLID &clid)
Standard constructor.
virtual StatusCode load(TTree *tree, INTuple *&refpObj)=0
Create the transient representation of an object.
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAddr) override
Convert the transient object to the requested representation.
virtual StatusCode book(const std::string &desc, INTuple *pObj, TTree *&tree)=0
Book a new N tuple.
StatusCode initialize() override
Initialize the converter.
virtual StatusCode readData(TTree *rtree, INTuple *pObj, long ievt)=0
Read N tuple data.
virtual std::string rootVarType(int)
Return ROOT type info:
StatusCode updateRep(IOpaqueAddress *pAddr, DataObject *pObj) override
Update the converted representation of a transient object.
SmartIF< INTupleSvc > m_ntupleSvc
Reference to N tuple service.
Definition RNTupleCnv.h:63
StatusCode finalize() override
Finalize the converter.
virtual TObject * tObj() const
Retrieve TObject* ptr.
This class is used for returning status codes from appropriate routines.
Definition StatusCode.h:64
bool isSuccess() const
Definition StatusCode.h:314
constexpr static const auto SUCCESS
Definition StatusCode.h:99
constexpr static const auto FAILURE
Definition StatusCode.h:100
@ WARNING
Definition IMessageSvc.h:22
@ ERROR
Definition IMessageSvc.h:22
bool parseName(const std::string &full, std::string &blk, std::string &var)
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.