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