| The Gaudi Framework v32r1 (f65d50dc)

RConverter.cpp
Go to the documentation of this file.
1 #define ROOTHISTCNV_RCONVERTER_CPP
2
3 // Include files
4 #include "RConverter.h"
5 #include "GaudiKernel/DataObject.h"
6 #include "GaudiKernel/IDataManagerSvc.h"
7 #include "GaudiKernel/IDataProviderSvc.h"
8 #include "GaudiKernel/IRegistry.h"
9 #include "GaudiKernel/MsgStream.h"
10 #include "GaudiKernel/SmartIF.h"
11 #include "RootObjAddress.h"
12
13 #include "TDirectory.h"
14 #include "TFile.h"
15 #include "TTree.h"
16 #include <list>
17 #include <string>
18
19 namespace {
20 std::map<std::string, TFile*> s_fileMap;
21 }
22
23 //-----------------------------------------------------------------------------
24 StatusCode RootHistCnv::RConverter::createDirectory( const std::string& loc )
25 //-----------------------------------------------------------------------------
26 {
27 MsgStream log( msgSvc(), "RConverter::createDir" );
28
29 // Get rid of leading /NTUPLES
30 std::string full = diskDirectory( loc );
31
32 std::string fil, cur, s;
33 TDirectory* gDir = gDirectory;
34
35 TFile* tf = nullptr;
36 if ( findTFile( loc, tf ).isSuccess() ) { tf->cd(); }
37
38 std::vector<std::string> lpath;
39 int i = 1;
40
41 auto p = full.find( ":", 0 );
42 if ( p != std::string::npos ) {
43 fil = full.substr( 0, p );
44 i = p + 1;
45 fil += ":/";
46 gDirectory->cd( fil.c_str() );
47 }
48
49 while ( ( p = full.find( "/", i ) ) != std::string::npos ) {
50 s = full.substr( i, p - i );
51 lpath.push_back( s );
52 i = p + 1;
53 }
54 lpath.push_back( full.substr( i ) );
55
56 if ( full.compare( 0, 1, "/" ) == 0 ) gDirectory->cd( "/" );
57
58 for ( const auto& litr : lpath ) {
59 cur = litr;
60 if ( !gDirectory->GetKey( litr.c_str() ) ) { gDirectory->mkdir( litr.c_str() ); }
61 gDirectory->cd( litr.c_str() );
62 }
63
64 gDirectory = gDir;
65
66 return StatusCode::SUCCESS;
67 }
68 //-----------------------------------------------------------------------------
69 std::string RootHistCnv::RConverter::diskDirectory( const std::string& loc )
70 //-----------------------------------------------------------------------------
71 {
72 // Get rid of leading /NTUPLES/{INPUT_STREAM} or /stat/{INPUT_STREAM}
73 std::string dir;
74 long lf1 = loc.find( "/NTUPLES/" );
75 long lf2 = loc.find( "/stat/" );
76 long ll;
77 if ( lf1 != -1 ) {
78 ll = loc.find( "/", lf1 + 9 );
79
80 } else if ( lf2 != -1 ) {
81 ll = loc.find( "/", lf2 + 6 );
82
83 } else {
84 MsgStream log( msgSvc(), "RConverter" );
85 log << MSG::ERROR << "diskDirectory(" << loc << ")"
86 << " --> no leading /NTUPLES/ or /stat/" << endmsg;
87 return loc;
88 }
89 // dir = loc.substr(ll+8);
90
91 if ( ll == -1 ) {
92 dir = "/";
93 } else {
94 dir = loc.substr( ll );
95 }
96
97 return dir;
98 }
99
100 //-----------------------------------------------------------------------------
101 std::string RootHistCnv::RConverter::directory( const std::string& loc )
102 //-----------------------------------------------------------------------------
103 {
104 return diskDirectory( loc );
105 }
106
107 //-----------------------------------------------------------------------------
108 void RootHistCnv::RConverter::setDirectory( const std::string& loc )
109 //-----------------------------------------------------------------------------
110 {
111 MsgStream log( msgSvc(), "RConverter" );
112 TFile* tf = nullptr;
113
114 std::string full = diskDirectory( loc );
115
116 // get associated TFile
117 if ( findTFile( loc, tf ).isSuccess() ) {
118 tf->cd();
119 } else {
120 log << MSG::ERROR << "error getting TFile name " << loc << endmsg;
121 }
122
123 int p, i = 1;
124 std::string cur, sdir;
125
126 gDirectory->cd( "/" );
127 while ( ( p = full.find( "/", i ) ) != -1 ) {
128 sdir = full.substr( i, p - i );
129 if ( !gDirectory->GetKey( sdir.c_str() ) ) {
130 log << MSG::ERROR << "cannot cd to " << full << " from " << gDirectory->GetPath() << endmsg;
131 return;
132 }
133 gDirectory->cd( sdir.c_str() );
134
135 i = p + 1;
136 }
137 gDirectory->cd( full.substr( i ).c_str() );
138 }
139
140 //-----------------------------------------------------------------------------
141 void RootHistCnv::RConverter::setDiskDirectory( const std::string& loc )
142 //-----------------------------------------------------------------------------
143 {
144 setDirectory( loc );
145 }
146
147 //-----------------------------------------------------------------------------
148 std::string RootHistCnv::RConverter::getDirectory()
149 //-----------------------------------------------------------------------------
150 {
151 return gDirectory->GetPath();
152 }
153
154 //-----------------------------------------------------------------------------
155 StatusCode RootHistCnv::RConverter::createAddress( DataObject* pObj, TDirectory* pDir, TObject* pTObj,
156 IOpaqueAddress*& refpAddr )
157 //-----------------------------------------------------------------------------
158 {
159 // Get address again....it does not change
160 IRegistry* pReg = pObj->registry();
161 if ( pReg ) {
162 refpAddr = pReg->address();
163 if ( !refpAddr ) {
164 refpAddr = new RootObjAddress( repSvcType(), objType(), pReg->name(), "", (unsigned long)( pDir ),
165 (unsigned long)( pTObj ), pTObj );
166
167 return StatusCode::SUCCESS;
168 }
169 }
170 return StatusCode::FAILURE;
171 }
172
173 //--------------------------------------------------------------------------
174 StatusCode RootHistCnv::RConverter::createAddress( const std::string& rzdir, const CLID& clid, const std::string& title,
175 TObject* pTObj, IOpaqueAddress*& refpAddress )
176 //--------------------------------------------------------------------------
177 {
178 auto pA = new RootObjAddress( repSvcType(), clid, rzdir, title, 0, 0, pTObj );
179
180 refpAddress = pA;
181 return StatusCode::SUCCESS;
182 }
183
184 //--------------------------------------------------------------------------
185 StatusCode RootHistCnv::RConverter::createAddress( const std::string& rzdir, const CLID& clid, long id, TObject* pTobj,
186 IOpaqueAddress*& refpAddress )
187 //--------------------------------------------------------------------------
188 {
189 auto obj = std::to_string( id );
190 StatusCode status = createAddress( rzdir, clid, obj, pTobj, refpAddress );
191 if ( status.isSuccess() ) {
192 unsigned long* ipar = (unsigned long*)refpAddress->ipar();
193 ipar[0] = id;
194 }
195 return status;
196 }
197
198 //-----------------------------------------------------------------------------
200 TDirectory* RootHistCnv::RConverter::changeDirectory( DataObject* pObject )
201 //-----------------------------------------------------------------------------
202 {
203 if ( pObject ) {
204 IRegistry* pReg = pObject->registry();
205 if ( pReg ) {
206 auto dataMgr = dataProvider().as<IDataManagerSvc>();
207 if ( dataMgr ) {
208 IRegistry* pParentReg = nullptr;
209 StatusCode status = dataMgr->objectParent( pReg, pParentReg );
210 if ( status.isSuccess() ) {
211 IOpaqueAddress* pParAddr = pParentReg->address();
212 if ( pParAddr ) {
213 TDirectory* pParentDir = (TDirectory*)pParAddr->ipar()[0];
214 if ( pParentDir ) {
215 gDirectory->cd( pParentDir->GetPath() );
216 return pParentDir;
217 }
218 }
219 }
220 }
221 }
222 }
223 return nullptr;
224 }
225
226 //-----------------------------------------------------------------------------
228 StatusCode RootHistCnv::RConverter::createRep( DataObject* pObject, IOpaqueAddress*& pAddr )
229 //-----------------------------------------------------------------------------
230 {
231 GlobalDirectoryRestore restore;
232 pAddr = nullptr;
233 try {
234 TDirectory* pParentDir = changeDirectory( pObject );
235 if ( pParentDir ) {
236 TObject* pTObj = createPersistent( pObject );
237 if ( pTObj ) {
238 pTObj->Write();
239 delete pTObj;
240 return createAddress( pObject, pParentDir, nullptr, pAddr );
241 }
242 }
243 } catch ( ... ) {}
244 MsgStream log( msgSvc(), "RConverter" );
245 log << MSG::ERROR << "Failed to create persistent Object!" << endmsg;
246 return StatusCode::FAILURE;
247 }
248
249 //-----------------------------------------------------------------------------
250 StatusCode RootHistCnv::RConverter::readObject( IOpaqueAddress* /* pAddr */, DataObject*& /* refpObj */ ) {
251 // MsgStream log(msgSvc(), "RConverter::readObject");
252 // log << MSG::WARNING << pAddr->par()[0] << " <> " << pAddr->par()[1]
253 // << " <> "
254 // << pAddr->ipar()[0] << " <> " << pAddr->ipar()[1] << " <> "
255 // << pAddr->registry()->identifier() << endmsg;
256
257 return StatusCode::SUCCESS;
258 }
259
260 //-----------------------------------------------------------------------------
261 TObject* RootHistCnv::RConverter::createPersistent( DataObject* /* pObj */ ) { return nullptr; }
262
263 //-----------------------------------------------------------------------------
264 StatusCode RootHistCnv::RConverter::regTFile( const std::string id, const TFile* tfile )
265 //-----------------------------------------------------------------------------
266 {
267 auto imap = s_fileMap.find( id );
268 if ( imap != s_fileMap.end() ) {
269 MsgStream log( msgSvc(), "RConverter" );
270 log << MSG::ERROR << "cannot register TTree " << id << ": already exists" << endmsg;
271 return StatusCode::FAILURE;
272 }
273 s_fileMap[id] = const_cast<TFile*>( tfile );
274
275 return StatusCode::SUCCESS;
276 }
277
278 //-----------------------------------------------------------------------------
279 StatusCode RootHistCnv::RConverter::findTFile( const std::string id, TFile*& tfile )
280 //-----------------------------------------------------------------------------
281 {
282 MsgStream log( msgSvc(), "RConverter" );
283 tfile = nullptr;
284
285 std::string idm;
286
287 // make sure we only get first two parts of id
288 int i1, i2, i3;
289 i1 = id.find( "/", 0 );
290 if ( i1 != 0 ) {
291 log << MSG::ERROR << "Directory name does not start with \"/\": " << id << endmsg;
292 return StatusCode::FAILURE;
293 }
294 i2 = id.find( "/", i1 + 1 );
295 if ( i2 == -1 ) {
296 log << MSG::ERROR << "Directory name has only one part: " << id << endmsg;
297 return StatusCode::FAILURE;
298 }
299 i3 = id.find( "/", i2 + 1 );
300 if ( i3 == -1 ) {
301 idm = id;
302 } else {
303 idm = id.substr( 0, i3 );
304 }
305
306 auto imap = s_fileMap.find( idm );
307 if ( imap == s_fileMap.end() ) return StatusCode::FAILURE;
308 tfile = imap->second;
309 return StatusCode::SUCCESS;
310 }
311 //-----------------------------------------------------------------------------
312 std::string RootHistCnv::RConverter::convertId( const std::string& id ) const
313 //-----------------------------------------------------------------------------
314 {
315 bool forced = false;
316 if ( id.size() > 0 && isdigit( id[0] ) ) {
317 try {
318 Gaudi::Property<bool> tmp;
319 tmp.assign( conversionSvc().as<IProperty>()->getProperty( "ForceAlphaIds" ) );
320 forced = tmp.value();
321 } catch ( ... ) {}
322 }
323 if ( forced )
324 return "h" + id;
325 else
326 return id;
327 }
328 //-----------------------------------------------------------------------------
329 StatusCode RootHistCnv::RConverter::error( const std::string& msg )
330 //-----------------------------------------------------------------------------
331 {
332 MsgStream log( msgSvc(), "RootHistCnv" );
333 log << MSG::ERROR << msg << endmsg;
334 return StatusCode::FAILURE;
335 }
RootHistCnv::RConverter::getDirectory
std::string getDirectory()
Definition: RConverter.cpp:148
details::size
constexpr auto size(const T &, Args &&...) noexcept
Definition: AnyDataWrapper.h:14
MsgStream
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
RootHistCnv::RConverter::diskDirectory
std::string diskDirectory(const std::string &loc)
Definition: RConverter.cpp:69
DataObject::registry
IRegistry * registry() const
Get pointer to Registry.
Definition: DataObject.h:72
RootHistCnv::RConverter::setDirectory
void setDirectory(const std::string &loc)
Definition: RConverter.cpp:108
Gaudi::Property
Implementation of property with value of concrete type.
Definition: Property.h:352
MsgStream.h
IDataManagerSvc
Definition: IDataManagerSvc.h:45
RootHistCnv::RConverter::createRep
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAddr) override
Convert the transient object to the requested representation.
Definition: RConverter.cpp:228
std::to_string
T to_string(T... args)
StatusCode::SUCCESS
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
RootHistCnv::RConverter::regTFile
StatusCode regTFile(const std::string, const TFile *)
Definition: RConverter.cpp:264
IRegistry::name
virtual const name_type & name() const =0
Name of the directory (or key)
RootHistCnv::RootObjAddress
Definition: RootObjAddress.h:11
RConverter.h
RootHistCnv::RConverter::findTFile
StatusCode findTFile(const std::string, TFile *&)
Definition: RConverter.cpp:279
getProperty
const char *PyHelper() getProperty(IInterface *p, char *name)
Definition: Bootstrap.cpp:237
RootHistCnv::RConverter::createDirectory
StatusCode createDirectory(const std::string &loc)
Definition: RConverter.cpp:24
std::map
STL class.
RootHistCnv::RConverter::changeDirectory
TDirectory * changeDirectory(DataObject *pObject)
Switch to object directory (=Parent directory)
Definition: RConverter.cpp:200
AvalancheSchedulerErrorTest.msgSvc
msgSvc
Definition: AvalancheSchedulerErrorTest.py:67
std::string
STL class.
Converter::msgSvc
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:95
std::vector::push_back
T push_back(T... args)
IDataManagerSvc.h
IDataProviderSvc.h
RootHistCnv::RConverter::createPersistent
virtual TObject * createPersistent(DataObject *pObj)
Create the persistent representation of an object.
Definition: RConverter.cpp:261
StatusCode
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
Gaudi::Property::value
const ValueType & value() const
Backward compatibility (.
Definition: Property.h:526
SmartIF.h
IRegistry.h
IRegistry
The IRegistry represents the entry door to the environment any data object residing in a transient da...
Definition: IRegistry.h:22
CLID
unsigned int CLID
Class ID definition.
Definition: ClassID.h:8
StatusCode::isSuccess
bool isSuccess() const
Definition: StatusCode.h:267
IRegistry::address
virtual IOpaqueAddress * address() const =0
Retrieve opaque storage address.
RootObjAddress.h
std::string::find
T find(T... args)
RootHistCnv::RConverter::directory
std::string directory(const std::string &loc)
Definition: RConverter.cpp:101
std::vector< std::string >
RootHistCnv::RConverter::error
StatusCode error(const std::string &msg)
Definition: RConverter.cpp:329
GlobalDirectoryRestore
Definition: RConverter.h:16
std::string::c_str
T c_str(T... args)
GaudiMP.FdsRegistry.msg
msg
Definition: FdsRegistry.py:8
gaudirun.s
string s
Definition: gaudirun.py:316
RootHistCnv::RConverter::convertId
std::string convertId(const std::string &) const
Definition: RConverter.cpp:312
StatusCode::FAILURE
constexpr static const auto FAILURE
Definition: StatusCode.h:86
RootHistCnv::RConverter::readObject
virtual StatusCode readObject(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create the transient representation of an object.
Definition: RConverter.cpp:250
MSG::ERROR
Definition: IMessageSvc.h:15
std::string::substr
T substr(T... args)
Gaudi::Property::assign
bool assign(const Details::PropertyBase &source) override
get the value from another property
Definition: Property.h:659
IOpaqueAddress
Opaque address interface definition.
Definition: IOpaqueAddress.h:23
DataObject
A DataObject is the base class of any identifiable object on any data store.
Definition: DataObject.h:30
IOpaqueAddress::ipar
virtual const unsigned long * ipar() const =0
Access to generic link parameters.
endmsg
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
RootHistCnv::RConverter::createAddress
StatusCode createAddress(DataObject *pObject, TDirectory *pDir, TObject *pTObject, IOpaqueAddress *&refpAddr)
Create address of the transient object according to the requested representation.
Definition: RConverter.cpp:155
DataObject.h
Gaudi.Configuration.log
log
Definition: Configuration.py:13
RootHistCnv::RConverter::setDiskDirectory
void setDiskDirectory(const std::string &loc)
Definition: RConverter.cpp:141