00001
00002 #define ROOTHISTCNV_RCONVERTER_CPP
00003
00004
00005 #include "GaudiKernel/IDataProviderSvc.h"
00006 #include "GaudiKernel/IDataManagerSvc.h"
00007 #include "GaudiKernel/IRegistry.h"
00008 #include "GaudiKernel/SmartIF.h"
00009 #include "GaudiKernel/DataObject.h"
00010 #include "GaudiKernel/MsgStream.h"
00011 #include "GaudiKernel/xtoa.h"
00012 #include "RConverter.h"
00013 #include "RootObjAddress.h"
00014
00015 #include "TDirectory.h"
00016 #include "TFile.h"
00017 #include "TTree.h"
00018 #include <string>
00019 #include <list>
00020
00021 namespace {
00022 std::map<std::string,TFile*> s_fileMap;
00023 }
00024
00025
00026 StatusCode RootHistCnv::RConverter::createDirectory(const std::string& loc)
00027
00028 {
00029 MsgStream log(msgSvc(), "RConverter::createDir");
00030
00031
00032 std::string full;
00033 full = diskDirectory( loc );
00034
00035 int p,i;
00036 std::string fil,cur,s;
00037 TDirectory *gDir;
00038
00039 gDir = gDirectory;
00040
00041 TFile *tf;
00042 if ( findTFile(loc,tf).isSuccess() ) {
00043 tf->cd();
00044 }
00045
00046 std::list<std::string> lpath;
00047 i = 1;
00048
00049 if ( (p=full.find(":",0)) != -1 ) {
00050 fil = full.substr(0,p);
00051 i = p+1;
00052 fil += ":/";
00053 gDirectory->cd(fil.c_str());
00054 }
00055
00056 while ( (p = full.find("/",i)) != -1) {
00057 s = full.substr(i,p-i);
00058 lpath.push_back(s);
00059 i = p+1;
00060 }
00061 lpath.push_back( full.substr(i,full.length()-i) );
00062
00063 if ( full.substr(0,1) == "/") {
00064 gDirectory->cd("/");
00065 }
00066
00067 std::list<std::string>::const_iterator litr;
00068 for(litr=lpath.begin(); litr!=lpath.end(); ++litr) {
00069 cur = *litr;
00070 if (! gDirectory->GetKey(litr->c_str()) ) {
00071 gDirectory->mkdir(litr->c_str());
00072 }
00073 gDirectory->cd(litr->c_str());
00074 }
00075
00076 gDirectory = gDir;
00077
00078 return StatusCode::SUCCESS;
00079 }
00080
00081 std::string RootHistCnv::RConverter::diskDirectory(const std::string& loc)
00082
00083 {
00084
00085 std::string dir;
00086 long lf1 = loc.find("/NTUPLES/");
00087 long lf2 = loc.find("/stat/");
00088 long ll;
00089 if (lf1 != -1) {
00090 ll = loc.find("/",lf1+9);
00091
00092 } else if (lf2 != -1) {
00093 ll = loc.find("/",lf2+6);
00094
00095 } else {
00096 MsgStream log(msgSvc(), "RConverter");
00097 log << MSG::ERROR << "diskDirectory(" << loc << ")"
00098 << " --> no leading /NTUPLES/ or /stat/" << endreq;
00099 return loc;
00100 }
00101
00102
00103 if (ll == -1) {
00104 dir = "/";
00105 } else {
00106 dir = loc.substr(ll,loc.length()-ll);
00107 }
00108
00109 return dir;
00110 }
00111
00112
00113 std::string RootHistCnv::RConverter::directory(const std::string& loc)
00114
00115 {
00116 return ( diskDirectory(loc) );
00117 }
00118
00119
00120 void RootHistCnv::RConverter::setDirectory(const std::string& loc)
00121
00122 {
00123 MsgStream log(msgSvc(), "RConverter");
00124 std::string full, id;
00125 TFile *tf;
00126
00127 full = diskDirectory( loc );
00128
00129
00130 if ( findTFile(loc,tf).isSuccess() ) {
00131 tf->cd();
00132 } else {
00133 log << MSG::ERROR << "error getting TFile name " << loc << endreq;
00134 }
00135
00136 int p,i=1;
00137 std::string cur,sdir;
00138
00139 gDirectory->cd("/");
00140 while ( (p = full.find("/",i)) != -1) {
00141 sdir = full.substr(i,p-i);
00142 if (! gDirectory->GetKey(sdir.c_str()) ) {
00143 log << MSG::ERROR << "cannot cd to " << full << " from "
00144 << gDirectory->GetPath() << endreq;
00145 return;
00146 }
00147 gDirectory->cd(sdir.c_str());
00148
00149 i = p+1;
00150 }
00151 gDirectory->cd( full.substr(i,full.length()-i).c_str() );
00152 }
00153
00154
00155 void RootHistCnv::RConverter::setDiskDirectory(const std::string& loc)
00156
00157 {
00158 setDirectory(loc);
00159 }
00160
00161
00162 std::string RootHistCnv::RConverter::getDirectory()
00163
00164 {
00165 std::string dir = gDirectory->GetPath();
00166 return (dir);
00167 }
00168
00169
00170
00171 StatusCode RootHistCnv::RConverter::createAddress(DataObject* pObj,
00172 TDirectory* pDir,
00173 TObject* pTObj,
00174 IOpaqueAddress*& refpAddr)
00175
00176 {
00177
00178 IRegistry* pReg = pObj->registry();
00179 if ( 0 != pReg ) {
00180 refpAddr = pReg->address();
00181 if ( 0 == refpAddr ) {
00182 refpAddr = new RootObjAddress(repSvcType(),
00183 objType(),
00184 pReg->name(),
00185 "",
00186 (unsigned long)(pDir),
00187 (unsigned long)(pTObj),
00188 pTObj);
00189
00190 return StatusCode::SUCCESS;
00191 }
00192 }
00193 return StatusCode::FAILURE;
00194 }
00195
00196
00197 StatusCode RootHistCnv::RConverter::createAddress(const std::string& rzdir,
00198 const CLID& clid,
00199 const std::string& title,
00200 TObject* pTObj,
00201 IOpaqueAddress*& refpAddress)
00202
00203 {
00204 RootObjAddress* pA = new RootObjAddress(repSvcType(),
00205 clid,
00206 rzdir,
00207 title,
00208 0,
00209 0,
00210 pTObj );
00211
00212 refpAddress = pA;
00213 return StatusCode::SUCCESS;
00214 }
00215
00216
00217
00218 StatusCode RootHistCnv::RConverter::createAddress(const std::string& rzdir,
00219 const CLID& clid,
00220 long id,
00221 TObject* pTobj,
00222 IOpaqueAddress*& refpAddress)
00223
00224 {
00225 char obj[32];
00226 StatusCode status = createAddress(rzdir, clid,
00227 ::_itoa(id, obj, 10), pTobj, refpAddress);
00228 if ( status.isSuccess() ) {
00229 unsigned long* ipar = (unsigned long*)refpAddress->ipar();
00230 ipar[0] = id;
00231 }
00232 return status;
00233 }
00234
00235
00237 TDirectory* RootHistCnv::RConverter::changeDirectory(DataObject* pObject)
00238
00239 {
00240 if ( pObject ) {
00241 IRegistry* pReg = pObject->registry();
00242 if ( pReg ) {
00243 SmartIF<IDataManagerSvc> dataMgr(dataProvider());
00244 if ( dataMgr.isValid() ) {
00245 IRegistry* pParentReg = 0;
00246 StatusCode status = dataMgr->objectParent(pReg, pParentReg);
00247 if ( status.isSuccess() ) {
00248 IOpaqueAddress* pParAddr = pParentReg->address();
00249 if ( pParAddr ) {
00250 TDirectory* pParentDir = (TDirectory*)pParAddr->ipar()[0];
00251 if ( pParentDir ) {
00252 gDirectory->cd(pParentDir->GetPath());
00253 return pParentDir;
00254 }
00255 }
00256 }
00257 }
00258 }
00259 }
00260 return 0;
00261 }
00262
00263
00265 StatusCode RootHistCnv::RConverter::createRep(DataObject* pObject,
00266 IOpaqueAddress*& pAddr)
00267
00268 {
00269 GlobalDirectoryRestore restore;
00270 pAddr = 0;
00271 try {
00272 TDirectory* pParentDir = changeDirectory(pObject);
00273 if ( pParentDir ) {
00274 TObject* pTObj = createPersistent(pObject);
00275 if ( pTObj ) {
00276 pTObj->Write();
00277 delete pTObj;
00278 return createAddress(pObject, pParentDir, 0, pAddr);
00279 }
00280 }
00281 }
00282 catch (...) {
00283 }
00284 MsgStream log (msgSvc(), "RConverter");
00285 log << MSG::ERROR << "Failed to create persistent Object!" << endreq;
00286 return StatusCode::FAILURE;
00287 }
00288
00289
00290 StatusCode RootHistCnv::RConverter::readObject(IOpaqueAddress* ,
00291 DataObject*& )
00292 {
00293
00294
00295
00296
00297
00298
00299 return StatusCode::SUCCESS;
00300 }
00301
00302
00303 TObject* RootHistCnv::RConverter::createPersistent(DataObject* )
00304 {
00305 return 0;
00306 }
00307
00308
00309
00310 StatusCode RootHistCnv::RConverter::regTFile(const std::string id,
00311 const TFile* tfile)
00312
00313 {
00314
00315 MsgStream log(msgSvc(), "RConverter");
00316
00317 std::map<std::string,TFile*>::const_iterator imap;
00318 imap = s_fileMap.find(id);
00319
00320 if ( imap != s_fileMap.end() ) {
00321 log << MSG::ERROR << "cannot register TTree " << id
00322 << ": already exists" << endreq;
00323 return StatusCode::FAILURE;
00324 }
00325
00326 s_fileMap[id] = const_cast<TFile*>(tfile);
00327
00328 return StatusCode::SUCCESS;
00329 }
00330
00331
00332 StatusCode RootHistCnv::RConverter::findTFile(const std::string id,
00333 TFile*& tfile)
00334
00335 {
00336 MsgStream log(msgSvc(), "RConverter");
00337 tfile = 0;
00338
00339 std::string idm;
00340
00341
00342 int i1,i2,i3;
00343 i1 = id.find("/",0);
00344 if (i1 != 0) {
00345 log << MSG::ERROR << "Directory name does not start with \"/\": "
00346 << id << endreq;
00347 return StatusCode::FAILURE;
00348 }
00349 i2 = id.find("/",i1+1);
00350 if (i2 == -1) {
00351 log << MSG::ERROR << "Directory name has only one part: " << id << endreq;
00352 return StatusCode::FAILURE;
00353 }
00354 i3 = id.find("/",i2+1);
00355 if (i3 == -1) {
00356 idm = id;
00357 } else {
00358 idm = id.substr(0,i3);
00359 }
00360
00361 std::map<std::string,TFile*>::const_iterator imap;
00362 imap = s_fileMap.find(idm);
00363
00364 if ( imap == s_fileMap.end() ) {
00365 return StatusCode::FAILURE;
00366 }
00367 tfile = (*imap).second;
00368 return StatusCode::SUCCESS;
00369 }
00370
00371 std::string RootHistCnv::RConverter::convertId(const std::string& id ) const
00372
00373 {
00374 bool forced = false;
00375 if ( id.size() > 0 && isdigit(id[0]) ) {
00376 try {
00377 BooleanProperty tmp;
00378 tmp.assign(SmartIF<IProperty>(conversionSvc())->getProperty( "ForceAlphaIds"));
00379 forced = (bool)tmp;
00380 }
00381 catch ( ... ) { }
00382 }
00383 if (forced ) return std::string("h") + id;
00384 else return id;
00385 }
00386
00387 StatusCode RootHistCnv::RConverter::error(const std::string& msg)
00388
00389 {
00390 MsgStream log(msgSvc(), "RootHistCnv");
00391 log << MSG::ERROR << msg << endmsg;
00392 return StatusCode::FAILURE;
00393 }
00394