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