Loading [MathJax]/extensions/tex2jax.js
The Gaudi Framework  v31r0 (aeb156f0)
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
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 {
21 }
22 
23 //-----------------------------------------------------------------------------
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 
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
102 //-----------------------------------------------------------------------------
103 {
104  return diskDirectory( loc );
105 }
106 
107 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
142 //-----------------------------------------------------------------------------
143 {
144  setDirectory( loc );
145 }
146 
147 //-----------------------------------------------------------------------------
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 //--------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
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 //-----------------------------------------------------------------------------
313 //-----------------------------------------------------------------------------
314 {
315  bool forced = false;
316  if ( id.size() > 0 && isdigit( id[0] ) ) {
317  try {
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 //-----------------------------------------------------------------------------
330 //-----------------------------------------------------------------------------
331 {
332  MsgStream log( msgSvc(), "RootHistCnv" );
333  log << MSG::ERROR << msg << endmsg;
334  return StatusCode::FAILURE;
335 }
std::string getDirectory()
Definition: RConverter.cpp:148
Definition of the MsgStream class used to transmit messages.
Definition: MsgStream.h:24
std::string diskDirectory(const std::string &loc)
Definition: RConverter.cpp:69
void setDirectory(const std::string &loc)
Definition: RConverter.cpp:108
Implementation of property with value of concrete type.
Definition: Property.h:352
const CLID & objType() const override
Retrieve the class type of objects the converter produces.
Definition: Converter.cpp:13
StatusCode createRep(DataObject *pObj, IOpaqueAddress *&refpAddr) override
Convert the transient object to the requested representation.
Definition: RConverter.cpp:228
bool isSuccess() const
Definition: StatusCode.h:267
T to_string(T...args)
constexpr static const auto SUCCESS
Definition: StatusCode.h:85
SmartIF< IMessageSvc > & msgSvc() const
Retrieve pointer to message service.
Definition: Converter.cpp:95
StatusCode regTFile(const std::string, const TFile *)
Definition: RConverter.cpp:264
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:80
StatusCode findTFile(const std::string, TFile *&)
Definition: RConverter.cpp:279
StatusCode createDirectory(const std::string &loc)
Definition: RConverter.cpp:24
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:200
constexpr auto size(const C &c) noexcept(noexcept(c.size())) -> decltype(c.size())
STL class.
T push_back(T...args)
SmartIF< IFace > as() const
return a new SmartIF instance to another interface
Definition: SmartIF.h:107
long repSvcType() const override
Definition: RConverter.h:37
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:261
This class is used for returning status codes from appropriate routines.
Definition: StatusCode.h:50
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:68
std::string directory(const std::string &loc)
Definition: RConverter.cpp:101
StatusCode error(const std::string &msg)
Definition: RConverter.cpp:329
T c_str(T...args)
string s
Definition: gaudirun.py:312
constexpr static const auto FAILURE
Definition: StatusCode.h:86
std::string convertId(const std::string &) const
Definition: RConverter.cpp:312
virtual StatusCode readObject(IOpaqueAddress *pAddr, DataObject *&refpObj)
Create the transient representation of an object.
Definition: RConverter.cpp:250
T substr(T...args)
bool assign(const Details::PropertyBase &source) override
get the value from another property
Definition: Property.h:658
const ValueType & value() const
Backward compatibility (.
Definition: Property.h:525
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:30
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
Definition: MsgStream.h:192
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:155
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:204
void setDiskDirectory(const std::string &loc)
Definition: RConverter.cpp:141