![]() |
|
|
Generated: 24 Nov 2008 |
00001 // $Id: RConverter.cpp,v 1.13 2007/01/08 17:16:02 mato Exp $ 00002 #define ROOTHISTCNV_RCONVERTER_CPP 00003 00004 // Include files 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 // Get rid of leading /NTUPLES 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 // Get rid of leading /NTUPLES/{INPUT_STREAM} or /stat/{INPUT_STREAM} 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 // dir = loc.substr(ll+8,loc.length()-ll-8); 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 // get associated TFile 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 // Get address again....it does not change 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* /* pAddr */ , 00291 DataObject*& /* refpObj */ ) 00292 { 00293 // MsgStream log(msgSvc(), "RConverter::readObject"); 00294 // log << MSG::WARNING << pAddr->par()[0] << " <> " << pAddr->par()[1] 00295 // << " <> " 00296 // << pAddr->ipar()[0] << " <> " << pAddr->ipar()[1] << " <> " 00297 // << pAddr->registry()->identifier() << endreq; 00298 00299 return StatusCode::SUCCESS; 00300 } 00301 00302 //----------------------------------------------------------------------------- 00303 TObject* RootHistCnv::RConverter::createPersistent(DataObject* /* pObj */) 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 // make sure we only get first two parts of id 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