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/" << endmsg;
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 << endmsg;
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() << endmsg;
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 std::ostringstream obj; obj << id;
00226 StatusCode status = createAddress(rzdir, clid, obj.str(), pTobj, refpAddress);
00227 if ( status.isSuccess() ) {
00228 unsigned long* ipar = (unsigned long*)refpAddress->ipar();
00229 ipar[0] = id;
00230 }
00231 return status;
00232 }
00233
00234
00236 TDirectory* RootHistCnv::RConverter::changeDirectory(DataObject* pObject)
00237
00238 {
00239 if ( pObject ) {
00240 IRegistry* pReg = pObject->registry();
00241 if ( pReg ) {
00242 SmartIF<IDataManagerSvc> dataMgr(dataProvider());
00243 if ( dataMgr.isValid() ) {
00244 IRegistry* pParentReg = 0;
00245 StatusCode status = dataMgr->objectParent(pReg, pParentReg);
00246 if ( status.isSuccess() ) {
00247 IOpaqueAddress* pParAddr = pParentReg->address();
00248 if ( pParAddr ) {
00249 TDirectory* pParentDir = (TDirectory*)pParAddr->ipar()[0];
00250 if ( pParentDir ) {
00251 gDirectory->cd(pParentDir->GetPath());
00252 return pParentDir;
00253 }
00254 }
00255 }
00256 }
00257 }
00258 }
00259 return 0;
00260 }
00261
00262
00264 StatusCode RootHistCnv::RConverter::createRep(DataObject* pObject,
00265 IOpaqueAddress*& pAddr)
00266
00267 {
00268 GlobalDirectoryRestore restore;
00269 pAddr = 0;
00270 try {
00271 TDirectory* pParentDir = changeDirectory(pObject);
00272 if ( pParentDir ) {
00273 TObject* pTObj = createPersistent(pObject);
00274 if ( pTObj ) {
00275 pTObj->Write();
00276 delete pTObj;
00277 return createAddress(pObject, pParentDir, 0, pAddr);
00278 }
00279 }
00280 }
00281 catch (...) {
00282 }
00283 MsgStream log (msgSvc(), "RConverter");
00284 log << MSG::ERROR << "Failed to create persistent Object!" << endmsg;
00285 return StatusCode::FAILURE;
00286 }
00287
00288
00289 StatusCode RootHistCnv::RConverter::readObject(IOpaqueAddress* ,
00290 DataObject*& )
00291 {
00292
00293
00294
00295
00296
00297
00298 return StatusCode::SUCCESS;
00299 }
00300
00301
00302 TObject* RootHistCnv::RConverter::createPersistent(DataObject* )
00303 {
00304 return 0;
00305 }
00306
00307
00308
00309 StatusCode RootHistCnv::RConverter::regTFile(const std::string id,
00310 const TFile* tfile)
00311
00312 {
00313
00314 MsgStream log(msgSvc(), "RConverter");
00315
00316 std::map<std::string,TFile*>::const_iterator imap;
00317 imap = s_fileMap.find(id);
00318
00319 if ( imap != s_fileMap.end() ) {
00320 log << MSG::ERROR << "cannot register TTree " << id
00321 << ": already exists" << endmsg;
00322 return StatusCode::FAILURE;
00323 }
00324
00325 s_fileMap[id] = const_cast<TFile*>(tfile);
00326
00327 return StatusCode::SUCCESS;
00328 }
00329
00330
00331 StatusCode RootHistCnv::RConverter::findTFile(const std::string id,
00332 TFile*& tfile)
00333
00334 {
00335 MsgStream log(msgSvc(), "RConverter");
00336 tfile = 0;
00337
00338 std::string idm;
00339
00340
00341 int i1,i2,i3;
00342 i1 = id.find("/",0);
00343 if (i1 != 0) {
00344 log << MSG::ERROR << "Directory name does not start with \"/\": "
00345 << id << endmsg;
00346 return StatusCode::FAILURE;
00347 }
00348 i2 = id.find("/",i1+1);
00349 if (i2 == -1) {
00350 log << MSG::ERROR << "Directory name has only one part: " << id << endmsg;
00351 return StatusCode::FAILURE;
00352 }
00353 i3 = id.find("/",i2+1);
00354 if (i3 == -1) {
00355 idm = id;
00356 } else {
00357 idm = id.substr(0,i3);
00358 }
00359
00360 std::map<std::string,TFile*>::const_iterator imap;
00361 imap = s_fileMap.find(idm);
00362
00363 if ( imap == s_fileMap.end() ) {
00364 return StatusCode::FAILURE;
00365 }
00366 tfile = (*imap).second;
00367 return StatusCode::SUCCESS;
00368 }
00369
00370 std::string RootHistCnv::RConverter::convertId(const std::string& id ) const
00371
00372 {
00373 bool forced = false;
00374 if ( id.size() > 0 && isdigit(id[0]) ) {
00375 try {
00376 BooleanProperty tmp;
00377 tmp.assign(SmartIF<IProperty>(conversionSvc())->getProperty( "ForceAlphaIds"));
00378 forced = (bool)tmp;
00379 }
00380 catch ( ... ) { }
00381 }
00382 if (forced ) return std::string("h") + id;
00383 else return id;
00384 }
00385
00386 StatusCode RootHistCnv::RConverter::error(const std::string& msg)
00387
00388 {
00389 MsgStream log(msgSvc(), "RootHistCnv");
00390 log << MSG::ERROR << msg << endmsg;
00391 return StatusCode::FAILURE;
00392 }
00393